What you want could possibly be achieved using low-level (plumbing) Git commands and a separate work tree and the index.
As explained in the git(1)
manual page, through the usage of environment variables it's possible to make a separate work tree for a given Git repository, basically:
$ mkdir foo && cd $_
$ export GIT_DIR=/path/to/the/repo/.git
$ export GIT_INDEX_FILE="$(pwd)/.index"
$ git read-tree master
$ git checkout-index -a -u
Now update the files in the work tree and stage the changes (git add
etc) and then
$ editor /tmp/COMMIT_MSG
$ git update-ref refs/heads/master $(git commit-tree $(git write-tree) -p $(git rev-parse master) </tmp/COMMIT_MSG)
This:
- Creates a tree from the index (
git write-tree
) and writes its SHA-1 name to stdout.
- Obtains the SHA-1 name of the commit pointed to by the branch "master".
- Creates a commit object using the SHA-1 name of the commit obtained on the previous step as the parent commit. The name of the commit object is printed to stdout.
- Updates the branch "master" to point to that new commit object.
This operates on a pretty low level using only the plumbing commands but not touch HEAD
in the repository and hence allows to work normally in the original work tree.
This is scriptable but is too cumbersome so I'd just try to use the git-new-workdir
script available in the contrib
section of the Git proper — it sets up a separate work tree linked to the original repository excluding the crucial stuff like HEAD
which might disrupt the work in the original work tree. So you could create the new work tree, check out "master" into it, record new commits on it then safely merge them in the original work tree which has "parallel" checked in.