* BUG? git stash and immediate git apply results in conflict @ 2022-06-01 6:55 Akos Vandra-Meyer 2022-06-02 6:32 ` Chris Torek 0 siblings, 1 reply; 4+ messages in thread From: Akos Vandra-Meyer @ 2022-06-01 6:55 UTC (permalink / raw) To: git Hello! I believe there might be a bug in how a git stash is calculated with the -k flag. I would expect to always be able to stash and pop a set of changes, but if the working directory contains staged and unstaged changes for a file, this results in a conflict. The stashed diff shows the changes from the last commit, rather than what is in the current working directory, so when the stash is applied it results in a conflict, because there are staged changes in the current working directory. Steps to reproduce: mkdir test cd test git init . echo foo > a echo bar >> a echo baz >> a git add a git commit -m "initial" cat a | sed s/bar/foo2/ > a2; mv a2 a git status git add a cat a | sed s/foo2/xxx/ > a2; mv a2 a git status git stash -ku git stash pop Thanks for looking into this, Akos Vandra-Meyer ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: BUG? git stash and immediate git apply results in conflict 2022-06-01 6:55 BUG? git stash and immediate git apply results in conflict Akos Vandra-Meyer @ 2022-06-02 6:32 ` Chris Torek 2022-06-02 11:31 ` Akos Vandra-Meyer 0 siblings, 1 reply; 4+ messages in thread From: Chris Torek @ 2022-06-02 6:32 UTC (permalink / raw) To: Akos Vandra-Meyer; +Cc: Git List On Wed, Jun 1, 2022 at 2:11 PM Akos Vandra-Meyer <axos88@gmail.com> wrote: > git stash -ku > git stash pop This is not a bug in `git stash` itself, but rather in the way you're using it. There are two mistakes on your part here: 1: You are using `-k`, aka `--keep-index`. This flag is intended for usages that are not yours here. 2. You are *not* using `--index` in your `git pop`. The `--index` flag is intended for the kind of thing you are doing here. It's a bit unfortunate (and perhaps worth some work in the documentation) that the `--keep-index` and `--index` flags sound so similar, and yet are so different. The documentation could use some examples here, I think. Note that if you *do* want to use `--keep-index` during the `git stash` step, you will need a `git reset --hard` before your `git stash apply --index && git stash drop` step (aka `git stash pop --index`). Chris ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: BUG? git stash and immediate git apply results in conflict 2022-06-02 6:32 ` Chris Torek @ 2022-06-02 11:31 ` Akos Vandra-Meyer 2022-06-02 12:24 ` Chris Torek 0 siblings, 1 reply; 4+ messages in thread From: Akos Vandra-Meyer @ 2022-06-02 11:31 UTC (permalink / raw) To: Chris Torek; +Cc: Git List Hi Chris, Thanks for getting back to me on this. My use case is the following: I made a bunch of (loosely related) changes to my code, but I have been asked to submit them as separate commits, so I need to separate the changes to dependent files relating to the first and second feature. So I need to separate the changes in my workdir into two commits (let's call them two features). Turns out the first feature needs a dependent file changed in one way, and the second feature improves on it, so it needs it changed in another way - normally this would result in a conflict if they would have been done separately in different branches. I start off by stashing everything except stuff directly relating to the first feature and stashing everything else. Check for build errors, unstage, and incrementally staging more stuff that need to be added in order to make the first feature build correctly. At some point I reach the file that has to be changed differently, so I will have a set of changes staged for that file, while another set of changes remain unstaged - the changes that will be required by the second feature. At this point you pointed out that apparantly I'm misusing git, but I am confused on how to correctly stash the unstaged changes to check if the code would build with the staged changes only, and unstage them and add more stuff if not? Thanks, Akos On Thu, 2 Jun 2022 at 08:32, Chris Torek <chris.torek@gmail.com> wrote: > > On Wed, Jun 1, 2022 at 2:11 PM Akos Vandra-Meyer <axos88@gmail.com> wrote: > > git stash -ku > > git stash pop > > This is not a bug in `git stash` itself, but rather in the way you're using it. > > There are two mistakes on your part here: > > 1: You are using `-k`, aka `--keep-index`. This flag is intended for usages > that are not yours here. > > 2. You are *not* using `--index` in your `git pop`. The `--index` flag is > intended for the kind of thing you are doing here. > > It's a bit unfortunate (and perhaps worth some work in the documentation) > that the `--keep-index` and `--index` flags sound so similar, and yet are so > different. The documentation could use some examples here, I think. > > Note that if you *do* want to use `--keep-index` during the `git stash` step, > you will need a `git reset --hard` before your `git stash apply --index && > git stash drop` step (aka `git stash pop --index`). > > Chris ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: BUG? git stash and immediate git apply results in conflict 2022-06-02 11:31 ` Akos Vandra-Meyer @ 2022-06-02 12:24 ` Chris Torek 0 siblings, 0 replies; 4+ messages in thread From: Chris Torek @ 2022-06-02 12:24 UTC (permalink / raw) To: Akos Vandra-Meyer; +Cc: Git List On Thu, Jun 2, 2022 at 4:31 AM Akos Vandra-Meyer <axos88@gmail.com> wrote: > Hi Chris, > > Thanks for getting back to me on this. > My use case is the following: > > I made a bunch of (loosely related) changes to my code, but I have > been asked to submit them as separate commits, so I need to separate > the changes to dependent files relating to the first and second > feature. I snipped the rest of this because I *dislike* and *recommend against* the use of `git stash` in the first place. If you want to use it that way, I am sure it is possible, but I recommend doing something else entirely. The rest of this message is all opinion! You seem to be looking for a recommended method, so I'm recommending mine. Let's say for concreteness that your current branch is named "topic". Here is what I would do (though I might change strategies and use various short-cuts depending on various sub-scenarios; this is meant for illustrating how to do what you want, in a way that provides the most clarity): git add (files as needed) git commit -m "final version, to be split up" git branch -m not-final-topic Then: # create a new topic branch git checkout -b new-topic <start-point> # get a view of commits git log HEAD..topic # copy some commits, up until some point git cherry-pick <some of those commits as desired> # begin splitting a commit: git cherry-pick -n <hash> # split it up: use a mix of the following: git reset / git add -p / git reset -p # as needed here to take part of the commit) # observe what's to be committed git diff --cached git commit # and write a commit message git add -p ... # as needed again git diff --cached git commit # repeat until satisfied with broken up commit(s) # make sure final result matches - optional: use the same # hash here as for the `git cherry-pick -n` command git diff HEAD <hash> # repeat copying whole and partial commits: git cherry-pick ... # add more whole commits as desired git cherry-pick -n ... # add commit that is to be split up # repeat the split-up process # When finally done, ensure that new-topic and not-final-topic # have the same contents. If they do, the split-up was successful. git diff not-final-topic HEAD Note that there is no longer any branch named "topic" at this point: we have instead "not-final-topic" and "new-topic". We can now rename "new-topic" to "topic" and use `git push -f` or whatever else is appropriate for whatever review system(s) you may be using. The entire process above can often be done with a single `git rebase -i` command, but that obscures the fundamental nature of what you're really doing. The repeated cherry-pick, reset, add -p, and/or reset -p sequence is what you're really doing: you are taking some set of existing commits, which are *close* to the commits you'd like to have, and rebuilding them to make a new set of commits (with different hash IDs) that represent what you really do want. In the end, you will have Git *find* your commits by name: the name "topic" will name the last commit in a chain of commits. The names here are up to you, and you can change any name at any time using `git branch -m`. Both Git and any review system you use is going to use the *commits*, with their scary looking hash IDs, but like you they will *find* these commits by starting from a branch name: so by changing the hash ID stored in the branch name, you change the set of commits they (and you) find. What `git stash` does is make several commits that are not on *any* branch. These commits are a little weird, requiring the use of the `git stash` command to access them. Ordinary commits on ordinary branches are not weird and do not need any special access, so that's what I prefer. But the fact that the stash commits are on *no* branch makes it easy to slide them from one branch to another without having to think about hash IDs; that's one reason some people prefer `git stash`. I'm just not one of those people. Chris ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-06-02 12:25 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-06-01 6:55 BUG? git stash and immediate git apply results in conflict Akos Vandra-Meyer 2022-06-02 6:32 ` Chris Torek 2022-06-02 11:31 ` Akos Vandra-Meyer 2022-06-02 12:24 ` Chris Torek
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.