Search code examples
gitbranchdiffgit-commit

Create git commit from diff in another branch without switching


I am wondering if it is possible to commit changes represented as a diff in a separate local branch without switching to this branch.

To put things in a perspective let's assume that I am working on the master branch and have a diff represented as a file raw.diff. Now I would like to apply this diff to the new local branch (or a tag) needs_change and commit changes without switching from the master.

I know that in a regular flow I would do something like this:

git checkout -b needs_change             # create and switch to local branch
git apply raw.diff                       # apply diff in needs_change
git commit -am "New commit with changes" # commit changes
git checkout master                      # switch back to master branch

However in this sequence of steps I have to switch to the needs_change branch and I am wondering if I can avoid this somehow.

Thanks in advance!


Solution

  • Technically, Git makes new commits from whatever is in the index, so you could swap out the current index (which normally matches the current commit) for some other index contents matching some other commit, and then adjust the index contents and use that to make another commit. The problem with doing this is that (a) it's really hard and (b) swapping out the index contents means overwriting the current work-tree anyway.

    Hence, the way to do this without making a separate clone is to add another work-tree and index, which you can do with git worktree add, provided your Git is at least 2.5.1 This actually adds a set of three items:

    • a new work-tree, as implied by the command git worktree add;
    • a new index to provide the index / staging-area for that new work-tree; and
    • a new HEAD to keep track of which branch is in that new work-tree.

    You can now cd into the new work-tree, do any work you like there, git add files to copy them back into the index for that work-tree, and git commit there to use that work-tree's index to build a new commit that updates the branch that is checked out in that work-tree.

    (If you don't have git worktree, just make another clone.)


    1Your Git should preferably be at least 2.15 since there were some important bug fixes leading up to 2.15. The most important one is that in 2.5 through 2.14, if you work in an added work-tree, and then get interrupted and leave it for 14 or more days, it's possible for Git to wreck what you were doing in that work-tree. If you just do something quickly, then remove the added work-tree, these bugs won't bite.