I believe that the best way to do what you want is to make your commits on top of a machine-specific branch, then move them using git to rebase . This is roughly what I am doing with my own home directory - essentially the same situation as yours.
If you accidentally transfer machine_1 before creating move_to_master, just create move_to_master, then reset machine_1 back to where it belongs, and follow the rest of the steps.
However, your question is worth answering, and I have provided a couple of alternatives below.
Creating commits not for the current branch
Precautions: Be very careful! This is scary!
You can fix a branch that is not checked by plumbing teams, just not necessarily very desirable. You should get your index in the state you need (it can be difficult), and then you can use git commit-tree :
git commit-tree -p $PARENT_COMMIT < $COMMIT_MESSAGE_FILE
This will print to display the newly created commit object on the SHA1 screen; if PARENT_COMMIT was the end of a branch, you should use git update-ref to update the branch to it:
git update-ref -m "commit: [commit subject]" $BRANCH $NEW_SHA1
If you create a script, you can achieve it in one layer as git update-ref -m ... $(git commit tree ...) . This is the worst step. If you update - return another branch to the wrong place, this sucks. You can still determine where to reset back with git reflog show $BRANCH .
In any case, it was just the easy part. The most difficult thing is to get the index in the state you need without checking the files. Two common commands you can use:
- git read-tree - reads information about trees into the index, but does not update the work tree at all (git checking is roughly equivalent to git read-tree, git checkout-index and git update-ref HEAD). You can use this so that the index contains the contents of this unfinished branch instead of HEAD.
- git update-index - changes the index. You can use this to add, delete or update files in the index from the work tree.
- git checkout-index - copy the given paths from the index to the work tree. After using read-tree, you can use this to get the individual file you want to modify, modify it, and then return it using the update index. The step of “changing it” can be complicated - for example, before doing all this, you can create a patch using git diff and then apply it using git here.
- git apply --cached Using the -cached option applies the patch directly to the version in the index without touching the work tree. Therefore, you can create diff, read-tree in another branch, apply it to the index, commit-tree and install. This is probably the most amazing way to do this.
The reason that all this is so complicated is that all the git commands that give you access to all of their powerful merge capabilities are dependent on the availability of files in the work tree. When you think about it, the task you are trying to do is merge - you have a difference in one branch, and you want to apply it to another. The way to get the result is to do a three-way merge using diff on the source branch, a common ancestor with another branch, and the tip of another branch. If you do not check another branch, you cannot merge it!
As usual, when you do things with the help of plumbing teams, you must be very careful to understand how everything works so that you do not terribly ruin your repository. However, I really used this with great effect when restructuring existing repositories (created by others ... don't ask). I only rewrote the commits in these cases - using read-tree and usually update-index, so it was much simpler than you are probably trying to do.
Alternative approaches
Having said all this, there are a few more approaches you could take to do what you want.
clone your repository. If you only keep track of configuration files, it will not take up much space, and everything will be much simpler. If you are really obsessive, you can even use the git new-workdir (version link in HEAD git.git) script to make only the working directory and not duplicate the rest of the repo (it uses symbolic links in the .git directory). Just remember, to be careful in completing a branch in one workdir that checked in another - the other will end up with a processing tree that is not synchronized.
writing a wrapper with one commit script is the closest thing to making one commit for another branch of all these options:
git commit orig_branch=$(git symbolic-ref HEAD) orig_branch=${orig_branch#refs/heads/} git checkout master git cherry-pick $orig_branch git checkout $orig_branch git reset --hard HEAD^