Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I pop git stash without triggering an auto-merge?

Tags:

git

The short version of this question is this: how can I pop the git stash without triggering an auto-merge?


Now for the longer version...

Consider the following toy example of an alternative to git stash ... + git pull ... + git pop.

First, git status shows that the only modification in the working directory is to some tracked file foo.

# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   foo
#
no changes added to commit (use "git add" and/or "git commit -a")

Now, in order to reset the working directory to a clean state, as a pre-requisite for running git pull, I temporarily rename the modified file foo (to some untracked name), and restore the version of foo in HEAD...

% mv foo foo.$(date +%Y%m%dT%H%M%S)
% git checkout foo
% git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   foo.20130508T110014
nothing added to commit but untracked files present (use "git add" to track)

OK, now I run git pull, which, for the sake of this example, we may assume is a fast-forward:

% git pull

Lastly, I restore the temporarily renamed foo.

% mv foo.20130508T110014 foo

...and I'm back to

% git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   foo
#

This is the "moral equivalent" of a git stash save + git pull + git stash pop, EXCEPT that the former, and not the latter, is immune to "merge conflicts", like this one:

% git stash save 'WIP'
% git pull
% git stash pop
Auto-merging foo
CONFLICT (content): Merge conflict in foo

How can I replicate the rename-checkout-pull-rename sequence above using git stash save + ... + git stash pop, without triggering an auto-merge?

Incidentally, the rename-checkout-...-rename routine more closely represents what I expect from a command called stash. In other words: save the state of my working directory now, and replace it later. There's no "merge" in this picture.

like image 751
kjo Avatar asked May 08 '13 15:05

kjo


People also ask

Does git stash pop do a merge?

git stash pop pops the top stash off of the stack and merges it with your working environment. Merging a stash can definitely result in conflicts, if there are committed changes that touch the same piece of work. Resolve these conflicts in the same way as you would when merging two branches.

How do I turn off auto merge in git?

Otherwise, select the files to be taken, stage them with git add and finally commit them with git commit . Restore the unwanted files then with git checkout -- filename . @marckassy: But you could then git reset HEAD and git add -p to select what you want. To shut off the initial merge completely, add -s ours .

How do you resolve stash pop and merge conflicts?

Manually (or ideally using some merge tool, see below) resolve the conflict(s). Use git restore --staged . to mark conflict(s) as resolved and unstage all files in the staging area. If you want to unstage only specific files, use the command git restore --staged <file> instead. You don't have to execute git add before.

How do I pop out git stash?

Retrieving stashed changes You can reapply stashed changes with the commands git stash apply and git stash pop . Both commands reapply the changes stashed in the latest stash (that is, stash@{0} ). A stash reapplies the changes while pop removes the changes from the stash and reapplies them to the working copy.


2 Answers

I belatedly realized that git already provides an extremely simple solution to the problem that motivated this question (namely an automatic merge with the potential to put the repository in a "unmerged state").

All one needs to do is to use

git stash branch <branchname> [<stash>]

instead of git stash pop (or git stash apply). Where <branchname> is the name of a new branch created by git for the purpose of applying the stashed changes.

This pops the stash in a way that is guaranteed to be free of conflicts.

like image 124
kjo Avatar answered Oct 11 '22 12:10

kjo


stash merges, that's just how it works.

You can achieve the non-merge-y stash with with write-tree read-tree and checkout-index. Here's a worked example for doing this to achieve a pristine test environment.

To just brute-force a no-merge stash apply, you could e.g.

git read-tree stash^{tree}
git checkout-index -af
like image 26
jthill Avatar answered Oct 11 '22 12:10

jthill