-{subsection: Merging} +{section: Merging} -{subsubsection: File renaming problems} +{subsection: File renaming problems} If, while merging, you encounter the following scary message: @@ -8,15 +8,60 @@ You'll get a whole lot of merge conflicts which one would imagine git could have taken care of. The problem, at least in my case, is that because detecting file name changes is currently an O(n^2) operation for git, which may take a long time--especially when you take into account the number of files in our repository. As such, git defines an upper limit on the search, so that it will stop after _m_ iterations. This limit defaults to 1, but can be set by changing the value of =diff.renamelimit= to something higher. A value of 400, in my case, seemed to do the trick. -{subsubsection: insufficient permission for adding an object} +{subsection: insufficient permission for adding an object} -If, while pushing to the repo in AFS, you encounter the following error message: +If, while pushing to the repo in AFS, you encounter one of the following error messages: insufficient permission for adding an object to repository database + error: unable to create temporary sha1 filename ./objects/fb: Permission denied + Something like git-gc must have run recently, and so directories in 'objects' need to be recreated. Git would do that as needed, but it doesn't know anything about AFS ACLs and is confused by the unix permissions it sees in our repo. The following *bash* shell commands may be used to rectify the situation: {code} cd /afs/cs.wisc.edu/p/condor/repository/CONDOR_SRC.git/objects for i in `seq 0 255`; do dir=`printf "%02x" $i`; mkdir -p $dir; done {endcode} + +{subsubsection:Details} + +Whenever git creates a directory under .git, it also sets the directory permissions, including the S_ISGID bit. This bit isn't supported under AFS, and the chmod() will fail with errno EACCES. This causes git to abort the entire push. Git uses S_ISGID to ensure all files have the same group, and not whatever primary group each committer has when they push. Explanation from a git maintainer: + +{code} +We fix directory permissions after creating any directory under .git +with the same code, so that in a repository shared by group, new +subdirectories created by a random somebody who belongs to that +group will belong to that group (we also chmod to g+wx in case such +a random somebody has overly strict umask). Instead of running +chown(2) on every new file created by us, we let the filesystem to +take care of it by telling the directories we create that new files +in them should inherit their group ownership. + +What we were worried about back when we decided to use S_ISGID was a +scenario like this: + +* A repository is shared by group "src". + +* A user belongs to the group "src". That group may or may not be + his primary group (i.e. "mkdir foo" done at random place by him + may not belong to the "src" group). + +* The user attempts to create a new branch "foo/bar" by pushing + from outside. There is no other branch whose name is + "foo/anything" when this happens. + +* An equivalent of "mkdir -p .git/refs/heads/foo" needs to be done + before an equivalent of "echo $sha >.git/refs/heads/foo/bar" + happens to accept this push. We want "foo" and "bar" to belong + to "src" group and they get appropriate permission bits suitable + to be accessed by the members of the "src" group. + +The story is the same for loose objects and their fan-out directory. +Storing a commit object fb/012345... may need to create the leading +fan-out ".git/objects/fb" and we want that directory and any future +files created in it to belong to the "src" group. + +Any alternative implementation that achieves the same result that +works on AFS can be substituted with the current code, or made +conditionally activated on AFS. +{endcode}