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.

[1]: 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

Reply via email to