Junio C Hamano wrote: > When we discuss "git add", the "one unit of work" is at much higher > level than that of "git update-index". "git add dir/" has to do a > lot more than "git add file", and "git add symlink" has to do quite > a different thing from "git add file", but to the end user, all of > them are about doing everything necessary to add what the user named > to the index. "git add submodule/" that does whatever necessary to > add the submodule to the index is still doing one thing well inside > the same framework, and that may include moving the $GIT_DIR and > turning it into a gitfile.
You're looking at it from an end-user point of view, while I'm looking at it from the implementation point of view. Here's a coarse simplification of what git add does: 1. Lock the index file, and grab a FILE handle to read/ write the file. 2. Update active_cache. Depending on the pathspec, we might be adding one entry or multiple entries, with different modes to the index. Nowhere did I say that it should add exactly one entry to active_cache with a predefined mode. Sure, tools that operate a lower layer of abstraction like update-index can be more picky about this. 3. Write tree and blob objects to the database corresponding to the worktree entries. Files and symbolic links get blob objects, while directories get tree objects. 4. Write active_cache to FILE handler we grabbed in step 1, and release the lock. What it does not do: 1. Move random files/ directory around in the worktree. 2. Mangle existing files in the worktree. (Although I know that the .gitmodules-mangling is coming soon, I'm not exactly elated with it ) 3. Write commit or tag objects to the database. 4. Update random refs. 5. Make coffee for the user to applaud him on the successful add. In my opinion, with some minor exceptions, all git tools follow these principles. Briefly, branch is a refs/heads/* helper, checkout is a HEAD + worktree helper, fetch is a receive-pack + refs/remotes/* helper, and reset is a bit of a swiss army knife that operates on HEAD + index + worktree. In general, I like git because commands don't create unnatural or heavy abstractions on top of these concepts. With some minor exceptions, all the commands are easy to understand and consistent. : This is what led to my OBJ_LINK proposal. > Not that I am saying I prefer "add --url=xxx". Quite the opposite. > I very much prefer the "clone and then add, but clone drops the > repository at the right place from the beginning" approach than "add > that knows about URL only for submodules", which is an ugly kludge. I don't know why you brought up the alternative in the first place. We both agree that it is git clone's job, although your reason is more superficial and mine's tied to the implementation. > If the user creates here/.git without gitlink with whatever means, > it is "git add here"'s job, if it wants to make it a submodule and > if it wants to make it possible to later check out another branch > that does not have the submodule, to stash away the repository and > turn it into gitfile, if it is part of what is needed to add a > submodule. I disagree. I think we should get a first-class tool to attach/ detach worktrees from a GITDIR. It can incoporate the logic from contrib/workdir/git-new-workdir to optionally create a worktree with an independent index, HEAD, and logs/HEAD. > Of course, we could start from teaching "submodule add" to do so, > and then internally redirect "git add subm" to "git submodule add", > but that is a minor implementation detail that does not affect the > end user experience. Yuck. Don't you care about the implementation, as long as it fixes the end-user's problem? -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html