简体   繁体   中英

How to git merge named branches A into B without touching my worktree?

I want to write a shell script, so that I can schedule a merge between two branches to happen at a specific time. However, since I might be working in another branch when that time is reached, I need it to happen in the background.

So, is there a simple way to merge branch A into branch B, without having to checkout B first?

A true (non fast-forward) merge is performed using the index—this is because in case of a conflict in a file you have to store the base and the both sides of that files in the index entry for it. git merge , being a porcelain command, also touches the work tree, but this is not required for the plumbing-level commands. So, to merge A into B you will need at least a separate index.

So you have these two options:

  • Use the git-new-workdir contrib script to turn arbitrary directory into a "shim" repository which has its own work tree, HEAD and the index but uses the object storage of the original Git repository.

    IMO, this is the simplest way unless you want to script the task to repeat it multiple times.

  • Use plumbing Git commands and environment variables to cook an environment suitable for performing a merge.

    You might either set aside the index and the work tree and perform a normal merge using git merge there; this , while deals with some other problem, explains how to set up separate index and work tree.

    Or you can pick a more hardcore route and use only the separate index and plumbing-level commands to perform an index-only merge. The key commands to do that (after setting a separate index aside) are:

    • git read-tree -m which perform an actual merge, and
    • git write-tree to make a tree object out of the index, and
    • git commit-tree to create a commit referring to that tree object.

You've got a worktree you want to protect, use another worktree. git clone 's cheap, it's built for this:

temp=$TMPDIR/temp
git clone -s . $temp -b B
( cd $temp; git merge origin/A && git push ) && rm -rf $temp

If there's merge conflicts temp won't be deleted, fix them, push, rm.

If you've got B checked out at the time the push will fail, git pull $temp when you're ready.


The clone will do a full checkout, which merge doesn't actually need to do its work. It's easy to avoid,

git clone -s . $temp -b B --no-checkout   # < add --no-checkout
cd $temp
git read-tree HEAD                        # < add read-tree HEAD
git merge
# ...

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