In Git, one can set up a repository with a "detached worktree", where
the .git directory is not a subdirectory of the top directory of the
work tree.

In general, Git commands on a repository with a detached worktree can
be executed by cd'ing into the directory containing the .git
directory, and executing the Git command there.  E.g., "git add" and
"git commit" execute as one would expect.  (I think they can also be
executed by cd'ing to the worktree and setting GIT_DIR.)

However, this approach does not work with "git filter-branch", which
objects with "You need to run this command from the toplevel of the
working tree."

I suspect that it does not work with other Git commands that are
implemented with shell scripts.  The problem appears to be in the
git-sh-setup script, which is called by the Git shell scripts to set
up the environment and do preliminary tests.

It seems to me that this inconsistency between the script commands and
the binary commands can be fixed by updating git-sh-setup in this way:

--- git-sh-setup.Custom.orig    2013-06-20 12:59:45.000000000 -0400
+++ git-sh-setup        2013-10-07 22:34:06.719946134 -0400
@@ -297,14 +297,18 @@
 # if we require to be in a git repository.
 if test -z "$NONGIT_OK"
-       GIT_DIR=$(git rev-parse --git-dir) || exit
+       export GIT_DIR=$(git rev-parse --git-dir) || exit
        if [ -z "$SUBDIRECTORY_OK" ]
-               test -z "$(git rev-parse --show-cdup)" || {
-                       exit=$?
-                       echo >&2 "You need to run this command from the 
toplevel of the working tree."
-                       exit $exit
-               }
+               cdup="$(git rev-parse --show-cdup)"
+               if [ -n "$cdup" ]
+               then
+                       # Current directory is not the toplevel.
+                       # Set GIT_DIR to the absolute path of the repository.
+                       GIT_DIR=$(cd "$GIT_DIR" && pwd)
+                       # cd to the toplevel.
+                       cd $cdup
+               fi
        test -n "$GIT_DIR" && GIT_DIR=$(cd "$GIT_DIR" && pwd) || {
                echo >&2 "Unable to determine absolute path of git directory"

What this change does is, when a command is invoked from a directory
containing a repository with a detached worktree, is to set GIT_DIR to
the directory of the repository, then cd to the top of the worktree.
After that, the script command should work as expected.

I am far from being an expert in Git internals, so I don't know
whether this is the correct approach to take to this problem or not.

Does anyone have any feedback on this?

To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to
More majordomo info at

Reply via email to