git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: BUG? git stash and immediate git apply results in conflict

From
Chris Torek <chris.torek@gmail.com>
Date
Jun 2, 2022, 12:24 UTC
Message-ID
<CAPx1GveKYjEoAnhJLkGOo9Esd5-vhkFkbz2Uwy10j5fxR_W9Bw@mail.gmail.com>
In-Reply-To
<CAHHcNodnB8gnaLgxW-vr6PxHh_YjCOAf7CTuot-CJsonb1mdnA@mail.gmail.com>
On Thu, Jun 2, 2022 at 4:31 AM Akos Vandra-Meyer <axos88@gmail.com> wrote:
Show 9 quoted lines
> 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
Previous: Akos Vandra-Meyer
Message 4 of 4 in “BUG? git stash and immediate git apply results in conflict”
  1. Akos Vandra-MeyerJun 1, 2022
  2. Chris TorekJun 2, 2022
  3. Akos Vandra-MeyerJun 2, 2022
  4. Chris TorekJun 2, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.