简体   繁体   中英

Shouldn't "git pull --rebase --autostash" always pop the stash automatically? Even when there are conflicts?

In a previous job, a couple of years ago, we used git with an (old) plugin, called " git up ".
https://github.com/aanand/git-up
"This plugin is no longer maintained or supported."
Updating your workspace used to be very easy:
just type "git up", see what files have conflicts, edit those to resolve the conflicts, do a "git add", and you are done.

I am now working for another company. They started to use git earlier this year. We don't have a clear and simple way for everyone to update our workspace. I would like to introduce a very simple way to update your workspace. As simple as possible . No commits, no merges.

It seems the simplest way to do this is by using "git pull" with the --rebase and --autostash flags. You can do the same by setting these values in your .gitconfig file. Or with an alias:

git config --global alias.up '!git fetch && git rebase --autostash origin'

This kinda works. When there are no conflicts, the stash pops automatically. Besides typing "git up" or "git pull --rebase --autostash", there is nothing I need to do.

There is one issue. When there are conflicts, git refuses to apply the stash back into my workspace. It says:

Applying autostash resulted in conflicts.
Your changes are safe in the stash.
You can run "git stash pop" or "git stash drop" at any time.
Successfully rebased and updated refs/heads/main.
$ git stash list
stash@{0}: autostash
$ 

When I then type "git stash pop" the stash is popped, my local changes are automatically edited into my workspace again (with the usual >>>> and <<<< markers). This always succeeds.

Note, git always refuses to automatically pop the stash when I have changed a file that is also changed on the remote repository. Not only when there is a real conflict (changes on the same lines). But also when my change is nowhere near the change from the remote repository. This makes me suspect that the behaviour I see is really not intended.

But why does --autostash not pop the stash automatically? I spoke with my company's git support persons. They also expect the stash to pop automatically. Even when there are conflicts. I did a bit of googling. Nothing I found suggests that the stash should not pop automatically.

So my question: What can I expect? Should the stash always pop automatically when I use --autostash? Or is the behaviour I see normal? Is this a bug? Did our local git-team change something in the executables or global config? (They say they didn't).

Behaviour is the same with 2.26.2 and 2.33. Thanks.

The behavior (er, behaviour) you see is normal, because the operation is still in progress . The autostash should be popped—or rather, dropped—after the operation is complete. It's true that in this case, the rebase portion of the operation is done, but the stash did not apply cleanly, so the git stash apply step has failed:

Applying autostash resulted in conflicts.

(I think Git did a git reset --hard to erase the attempt to git stash apply , making you do it on your own at this point, but I don't use autostash. Note that running git stash pop will get conflicts and will only apply , not drop, the stash.)

I personally dislike autostash because it's overly complicated: it consists of a multi-step operation, involving making stash commits, rebasing, then applying-and-dropping the stash commits. Instead of stashing , I recommend that you just commit before rebasing . This way the last commit is part of the rebase, so there's just one operation to finish.

You can use git reset to remove the rebased commit once you're all done, if that's even needed: I like to have smaller commits that I can combine later when they're "ready for prime time" as it were, and leaving a bunch of small "this isn't what I want but it's progress" commits in my in-progress work helps that out. Eventually, I run a git rebase -i , or series of them, to sort and combine the mini-commits.

(Not to make this a mini-rant against git stash , but ... git stash itself is bad in general. Avoid it.)

It turns out this is a bug. When using autostash, the stash is supposed to pop automatically. Even when there are conflicts. As I expected. Somewhere earlier this year (or last year) someone broke that functionality. I checked the lastest version ("next") of the git source code. And the pop again happens automatically.

There is one remaining problem. After the pop, and after the changes get applied without problems, I expect the stash to get deleted (dropped) automatically too. That doesn't happen. I don't know if that is intentionally, or also a bug. I suspect it is a bug. If everything applies fine, why keep the stash? I bet nobody knows and nobody dares to make a decision to fix this or not.

The sad thing is: I asked a whole bunch of people whether current behaviour (no automatic pop) is intentional or a bug. Colleagues, the guy who installed/maintains our git, our in-house git support people, our local git-experts, our external git-support team. And here. I got a zillion answers. None of them were correct. Most didn't even answer the question: "I don't like rebase, I don't like autostash, I don't like stash, why don't you do what I do, that is way better". And nobody actually answered my question. I don't blame the people here who tried to answer, but after 2 months rowing against the stream, I got a bit irritated. Sorry.

I'm happy I persisted. I'm happy the problem will be fixed soon. Now the only thing remaining is to make sure the stash gets dropped when we don't need it anymore. If necessary, I'll fix it myself and offer the fix to the git repository.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM