Re: [PATCH] Rename git-config-set to git-repo-config
From: Junio C Hamano <hidden>
Date: 2016-06-15 22:42:13
Linus Torvalds [off-list ref] writes:
Please don't. We should just make the scripts do it automatically instead.
Don't worry, we are in agreement about that goal.
"git-rev-parse" already has support for all of this, and you can do GIT_DIR=$(git-rev-parse --git-dir) GIT_PREFIX=$(git-rev-parse --show-prefix) where the first one shows the GIT_DIR, and the second one shows where in a git directory we are (empty if we're at the root).
Not in one case -- out-of-tree GIT_DIR. That is what GIT_WORKING_TREE is about.
In fact, I'd prefer if _every_ command just did the right thing inside a subdirectory.
Of course. The case your patch does not cover that I am worried about is where GIT_DIR is totally out of the tree. Something like GIT_DIR=/home/torvalds/uemacs.git and working tree at /tmp/uemacs. There is currently no way for the tools to figure out where the working tree toplevel is in such an arrangement, and that is when GIT_WORKING_TREE becomes useful. Under normal use pattern, with GIT_DIR not in such a funny place but immediately under working tree root, you do not need GIT_DIR nor GIT_WORKING_TREE. We can figure things ourselves by chdir()-up and looking for '.git/' directory.
I sent out this patch a week or two ago - it still applies, and it still mostly does the right thing. It makes at least "gitk" work right inside a subdirectory, and might make things like "git commit" and friends do the same.
I am afraid it needs more work --- as long as a script uses only C-level that use setup_git_directory(), everything should work, and in such a case you do not even need sh-setup --- asking "git-rev-parse --git-dir" is enough, just like you did in git-add. If the script does not have to know where GIT_DIR is (and I do not think gitk needs to know it, although it digs there by hand), it does not even need to do that. As you said, git-log and git-whatchanged works without any funny trick and are fine examples of that.
More testing still needed, but I think this is going in the right direction. Comments? I got none the first time around.
Among the ones I looked at that use git-sh-setup in
Documentation directory of git.git:
- git-checkout nor git-reset do not work because git-read-tree
does not use setup_git_directory(), and git-sh-setup does not
export GIT_DIR.
And exporting GIT_DIR from git-sh-setup is not a solution.
To setup_git_directory(), existence of GIT_DIR environment
currently means you cannot tell where your toplevel is
anymore. We could check GIT_DIR against getcwd() and if it
is a grand*parent directory, do an appropriate thing
including chdir("$GIT_DIR/..") and returning an adjusted
prefix, but we don't. And that would not work if GIT_DIR is
really out-of-tree anyway.
That is why I keep saying GIT_WORKING_TREE. We could export
both GIT_DIR and GIT_WORKING_TREE from git-sh-setup, and
teach the C-level commands that need access to working tree
to look at it, just like we default GIT_OBJECT_DIRECTORY from
git-sh-setup. People with out of tree GIT_DIR needs to
export both GIT_DIR and GIT_WORKING_TREE to override both,
just like people with object directory in nonstandard place
need to export GIT_OBJECT_DIRECTORY.
Maybe GIT_WORKING_TREE can default to "$GIT_DIR/..", just
like GIT_OBJECT_DIRECTORY defaults to "$GIT_DIR/objects".
Another obvious approach is to stop supporting out-of-tree
GIT_DIR, but I suspect that probably means we should ignore
GIT_DIR environment and always chdir()-up to find .git/
(which is fine and sane but is probably an uncomfortably big
change).
- git-prune does not work because git-fsck-objects does not
know where GIT_DIR is (again, GIT_DIR not exported).
- git-tag works.
Here is a list of C-level and their subdirectory-readiness
status.
These do not look at .git at all -- automatically subdirectory
ready ;-):
check-ref-format get-tar-commit-id git index-pack
mailinfo mailsplit patch-id shell show-index stripspace
verify-pack
Uses setup_git_directory() and subdirectory ready:
cat-file config-set diff-files diff-index diff-stages
diff-tree ls-files name-rev rev-list rev-parse
show-branch symbolic-ref update-index update-ref var
Uses enter_repo() to work from the toplevel:
daemon receive-pack upload-pack
Wants GIT_DIR to know where it is and working tree access is
always toplevel:
apply checkout-index clone-pack commit-tree
convert-objects fetch-pack fsck-objects hash-object
http-fetch http-push init-db local-fetch ls-tree
merge-base merge-index mktag pack-objects pack-redundant
peek-remote prune-packed read-tree send-pack ssh-fetch
ssh-upload tar-tree unpack-file unpack-objects
update-server-info write-tree