Git development
 help / color / mirror / Atom feed
* Re: [RFC] Introduce "git stage" (along with some heresy)
From: Marko Macek @ 2006-12-01 20:44 UTC (permalink / raw)
  To: git
In-Reply-To: <87slfzfri7.wl%cworth@cworth.org>

Carl Worth wrote:
> [This message, (yes,another long one from me), proposes 3 changes. The
> first should be uncontroversial I think, while the second and third
> are clear heresy, (and the second would require some amount of
> re-training or re-configuration by existing git user). Pick and choose
> as you see fit. I don't think they actually depend on each other,
> though I'll present them here as parts of a whole.]

/me likes (both emails).

Q: should git-commit require either -a or --staged when there is a
staged commit?

Mark

^ permalink raw reply

* Re: [RFC] Submodules in GIT
From: Martin Waitz @ 2006-12-01 20:30 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: sf, git
In-Reply-To: <Pine.LNX.4.64.0612011134080.3695@woody.osdl.org>

[-- Attachment #1: Type: text/plain, Size: 110 bytes --]

hoi :)

Linus, you are a lot better in describing all my thoughts than I myself.
;-)

-- 
Martin Waitz

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [RFC] Submodules in GIT
From: Linus Torvalds @ 2006-12-01 20:13 UTC (permalink / raw)
  To: sf; +Cc: git, Martin Waitz
In-Reply-To: <457061A7.2000102@b-i-t.de>



On Fri, 1 Dec 2006, sf wrote:
>
> Linus Torvalds wrote:
> ...
> > Think of it this way: one common use for submodules is really to just
> > (occasionally) track somebody elses code. The submodule should be a
> > totally pristine copy from somebody else (ie it might be the "intel driver
> > for X.org" submodule, maintained within intel), and the supermodule just
> > refers to it indirectly (ie the supermodule might be the "Fedora Core X
> > group" which contains all the different drivers from different people).
> 
> Could you please be a little bit more specific about how you would store the
> "pristine copy".

Note that it's not necessarily "pristine", since the submodule clearly is 
a local git repository in its own right. So like _any_ git repository, you 
can (and may well end up) having your own local branches in the submodule, 
with your own local modifications.

So I'm not claiming that a submodule must always match some external git 
tree 100%, and that it must be read-only or anything like that. I'm just 
saying that I suspect that quite often, one of the MOST IMPORTANT parts is 
that the submodule is really something that somebody else technically 
maintains, and that this is actually one of the _reasons_ why it is a 
submodule in the first place. 

For example, a lot of projects end up having some kind of "library 
component" as a submodule. Take something like a video player project, 
which would have something like ffmpeg as a submodule, not because you'd 
maintain ffmpeg yourself, but simply because (let's say) the library 
interface changes enough, or you need a specific version with some of your 
own fixes that haven't been released widely yet, so you want to carry all 
the libraries you need _with_ you, even though you don't really maintain 
that submodule. You at most have some small extensions of your own.

Now, in this situation, it's relaly really _important_ that the submodule 
really is totally independent of the supermodule, for several reasons.

For example, since you don't "really" own that project, carrying around 
your own fixes is really really painful. We know it happens all the time, 
and a lot of projects end up needing their own version, but the _last_ 
thing you want is to be in merge hell all the time. So as a supermodule 
maintainer, the best possible thing for you is to be able to push back 
those local changes to the original project maintainer, so that you 
_don't_ have to maintain your own changes.

But you need to realize that the real maintainer of the submodule is 
TOTALLY UNINTERESTED in your supermodule. He's not going to maintain it, 
and in fact, if you have anything in the submodule that ends up talking 
about your supermodule, that's just going to make it a lot less likely 
that the upstream maintainer will ever pull your changes. He might take a 
diff from you, but in a perfect world, you'd actually be able to tell him: 

 "Hey, I've got a git repository with a few fixes to your ffmpeg git tree, 
  please pull from git://myhost.com/submodule.git to get these fixes:

	... explanation of fixes and commits that are relevant to
	ffmpeg, and have nothing to do with the supermodule, except
	that you need those bug-fixes because you _use_ ffmpeg ...

  Thanks"

See?

So this is why it's really important that the submodule really is a git 
repository in its own right, and why committing stuff in the supermodule 
NEVER affect the submodule itself directly (it might _cause_ you to also 
do a commit in the submodule indirectly, but the submodule commit MUST be 
totally independent, and stand on its own).

Now, you don't _have_ to push things upstream, of course. You can always 
just maintain your own submodule branch, and every once in a while, inside 
the submodule, you do

	# fetch the development in the origin/master branch
	git fetch submodule-origin origin/master

	# rebase our own special magic sauce on top of that
	git rebase origin/master

to update your submodule, and _then_ you do a commit in the supermodule 
(after testing that the update is all ok, of course) which will update the 
"commit" pointer in the supermodule.

Notice? In this example, we really maintained the submodule AS a 
submodule. It was independent, but tied into the supermodule, so that when 
we clone the supermodule, or do things like bisection on a supermodule, we 
always end up cloning the submodule too (and in the case of bisection, we 
really only bisect the supermodule, but the submodule always gets 
"tracked" in the sense that we would always check out the state of the 
submodule that was appropriate for that particular commit in the 
supermodule).

> There seems to be some agreement to store the commit id of
> the submodule instead of a plain tree id in the supermodules tree object, and
> that all objects that are reachable from this commit are made part of the
> supermodule repository (either fetched or via alternates). Do you agree?

Well, I would actually argue that you may often want to have a supermodule 
and then at least have the _option_ to decide to not fetch all the 
submodules.

For an example of this kind of usage, let me tell you how we operated at 
Transmeta a few years ago, which I'm not saying is the _only_ way to 
operate, but it's ONE way to do it, and I'll also explain _why_ we did it, 
and why we had submodules.

In the case of transmeta, we had our own tools, our own programs, and we 
"owned" all of those. We _also_ used a lot of external tools, like gcc 
etc. However, different people worked on different parts, and if you 
worked on the actual x86 JIT part, you probably didn't want to have all of 
the gcc stuff in your tree _too_. That just took a lot of space, and you 
really didn't want to compile the whole toolchain (which took hours), 
since there were precompiled binaries readily available.

Still, from a _release_ standpoint, when we released a new binary, that 
binary very much depended not just on the actual JIT sources, but on the 
whole toolchain. So if you wanted to be able to re-create a release, you 
really needed _everything_. You couldn't just take the "current version" 
of the toolchain, you needed to have the toolchain that was used AT THE 
TIME OF THE RELEASE.

And this is a _classic_ example of when you'd want to use submodules. 
Notice how everybody wanted _some_ of the submodules, but really only the 
release people wanted them _all_. The higher up the chain you were, the 
less likely you were to really want to muck around with the compiler and 
the linker, for example. 

And nobody really owned all modules. 

So what you really want is:

 - a supermodule maintainer that is not really the maintainer of _any_ of 
   the submodules, but that does the main "build world" infrastructure 
   (and generally would tend to also maintain the source control 
   infrastructure itself)

 - submodules that had their own maintainers, and where the maintainers 
   may or may not have wanted the supermodule, but even when they wanted 
   the supermodule, they might not want _all_ of the submodules, simply 
   because they just didn't care.

 - some of the submodules then have _upstream_ sources that were totally 
   independent, and that you would want to track, but you had zero power 
   AT ALL over them, and yet you migt well want to push back at least some 
   of the fixes you did - at least the ones that made sense even outside 
   your own project - just to avoid having to maintain a _huge_ set of 
   internal patches.

So no, I don't think the supermodule should even _force_ people to always 
get all the submodules. It migth be the default case, but at the same 
time, it's just being polite to let users decide on their own whether they 
really want _all_ of the build infrastructure sources.

> If I understand you correctly you cannot make any changes to the submodules
> code _in the supermodule's repository_, no bugfixes, no extensions, no
> adaptions, nothing. Do you mean that?

Yes. I think you should make all changes _within_ the submodule, because 
the submodule should still be an independent git tree in its own right.

But obviously, you'd often use a private _branch_ in the submodule beause 
you end up having whatever private extensions. That's always true: we 
always have the "master" branch that is kind of the default "private 
branch" for any repository, but obviously that is often extended upon, and 
you may have several private branches. 

For example, after you've done a big update (from some external upstream 
source) in the submodule that you are using, you migth decide that you do 
all the work on that new big update in a _new_ private branch within the 
submodule - and get the submodule changes all squared away on its own 
_before_ you then decide to commit the end result (the tip of that new 
private branch) within the supermodule.

Ie, you very much should be able to to do

	git clone supermodule/that/one/submodule my-own-version-of-submodule

to clone a submodule _without_ getting anything else (but still get all 
the work you did within he submodule - very much including your own 
private branch work).

And the importance of keeping the submodule independent is partly just 
stability and sanity, but partly also scalability. For example, the 
"index" in a supermodule should NOT include the indexes of all the 
submodules. That's really important, because the index doesn't really 
scale. Things do slow down with large indexes. 

For example, git can handle tens of thousands of files easily. I suspect 
it scales well to hundreds of thousands of filenames. But with 
supermodules, you really can end up in the situation where you have _tens_ 
of these submodules, maybe even hundreds. And if you try to maintain one 
unified index for the _whole_ thing, I guarantee you that you'll start 
feeling the pain. Indexing millions of files is just not going to be 
pretty.

So just from a git stability and scalability point, it's important to keep 
subprojects _separate_. There is obviously integration stuff, but they 
should still be seen as truly independent projects. Even the supermodule 
should have clearly its own life even _regardless_ of submodules, because 
(as I said) quite often you may want the supermodule, but you don't want 
to have _all_ of the submodules.

But it's more than that stability and scalability thing too - keeping them 
separate is what allows you to do pulls and pushes on an individual 
subproject basis, and have people really work at that level. For example, 
if you're the compiler guy at a company, you really do want to work with 
other compiler people _outside_ the company, but you sure as hell may not 
be able to give them access to your supermodule. But you may want to work 
on _just_ the compiler parts (or at least share some branches in public), 
which means that the subproject really has to be able to work 
_independently_ of the supermodule.

So "independent" here is really key, for several reasons. And that all 
means, for example, that here must NEVER be any "backpointers". A 
subproject really can _never_ have backpointers to the superproject, 
because that fundamentally means that the above kind of "compiler guy 
works on the compiler subproject in public" cannot work, if your 
supermodule isn't public.


^ permalink raw reply

* [PATCH] make 'git add' a first class user friendly interface to the index
From: Nicolas Pitre @ 2006-12-01 20:06 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

I personally think this is going to make the GIT experience lot more 
enjoyable for everybody.  This brings the power of the index up front 
using a proper mental model without talking about the index at all. See 
for example how all the technical discussion has been evacuated from the 
git-add man page.

Any content to be committed must be added together.  Whether that 
content comes from new files or modified files doesn't matter.  You just 
need to "add" it, either with git-add, or by providing git-commit with 
-a (for already known files only of course). No need for a separate 
command to distinguish new vs modified files please.  That would only 
screw the mental model everybody should have when using GIT.

Signed-off-by: Nicolas Pitre <nico@cam.org>

---

TODO:

maybe add a -f/--force argument to allow for adding ignored files 
instead of going through git-update-index.

maybe add --new-only and --known-only arguments if there is a real need 
to discriminate between new vs updated files.  I would not suggest 
against it though, because if someone really has such fancy and uncommon 
requirements he might just use git-update-index directly at that point.

diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index 6342ea3..ffa8446 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -3,7 +3,7 @@ git-add(1)
 
 NAME
 ----
-git-add - Add files to the index file
+git-add - Add file content to the changeset to be committed next
 
 SYNOPSIS
 --------
@@ -11,16 +11,31 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
-A simple wrapper for git-update-index to add files to the index,
-for people used to do "cvs add".
-
-It only adds non-ignored files, to add ignored files use
+Contrary to other SCMs, with GIT you have to explicitly "add" all the
+changed file content you want to commit together to form a changeset
+with the 'add' command before using the 'commit' command.
+
+This is not only for adding new files.  Even modified files must be
+added to the set of changes about to be committed. This command can
+be performed multiple times before a commit. The 'git status' command
+will give you a summary of what is included for the next commit.
+
+Note: don't forget to 'add' a file again if you modified it after the
+first 'add' and before 'commit'. Otherwise only the previous added
+state of that file will be committed. This is because git tracks
+content, so what you're really 'add'ing to the commit is the *content*
+of the file in the state it is in when you 'add' it. Of course there are
+legitimate usage cases for not updating an already added file content
+in order to commit a previous file state, but in this case you better
+know what you're doing.
+
+This command only adds non-ignored files, to add ignored files use
 "git update-index --add".
 
 OPTIONS
 -------
 <file>...::
-	Files to add to the index (see gitlink:git-ls-files[1]).
+	Files to add content from.
 
 -n::
         Don't actually add the file(s), just show if they exist.
@@ -34,27 +49,12 @@ OPTIONS
 	for command-line options).
 
 
-DISCUSSION
-----------
-
-The list of <file> given to the command is fed to `git-ls-files`
-command to list files that are not registered in the index and
-are not ignored/excluded by `$GIT_DIR/info/exclude` file or
-`.gitignore` file in each directory.  This means two things:
-
-. You can put the name of a directory on the command line, and
-  the command will add all files in it and its subdirectories;
-
-. Giving the name of a file that is already in index does not
-  run `git-update-index` on that path.
-
-
 EXAMPLES
 --------
 git-add Documentation/\\*.txt::
 
-	Adds all `\*.txt` files that are not in the index under
-	`Documentation` directory and its subdirectories.
+	Adds content from all `\*.txt` files under `Documentation`
+	directory and its subdirectories.
 +
 Note that the asterisk `\*` is quoted from the shell in this
 example; this lets the command to include the files from
@@ -62,15 +62,17 @@ subdirectories of `Documentation/` directory.
 
 git-add git-*.sh::
 
-	Adds all git-*.sh scripts that are not in the index.
+	Considers adding content from all git-*.sh scripts.
 	Because this example lets shell expand the asterisk
 	(i.e. you are listing the files explicitly), it does not
-	add `subdir/git-foo.sh` to the index.
+	consider `subdir/git-foo.sh`.
 
 See Also
 --------
 gitlink:git-rm[1]
-gitlink:git-ls-files[1]
+gitlink:git-mv[1]
+gitlink:git-commit[1]
+gitlink:git-update-index[1]
 
 Author
 ------
diff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt
index fe4491d..8113d79 100644
--- a/Documentation/tutorial.txt
+++ b/Documentation/tutorial.txt
@@ -87,14 +87,54 @@ thorough description.  Tools that turn commits into email, for
 example, use the first line on the Subject line and the rest of the
 commit in the body.
 
-To add a new file, first create the file, then
-
-------------------------------------------------
-$ git add path/to/new/file
-------------------------------------------------
-
-then commit as usual.  No special command is required when removing a
-file; just remove it, then tell `commit` about the file as usual.
+GIt tracks content not files
+----------------------------
+
+Contrary to other SCMs, with GIT you have to explicitly "add" all
+the changed _content_ you want to commit together to form a changeset.
+This can be done in a few different ways:
+
+1) By using 'git add <file_spec>...'
+ 
+   This can be performed multiple times before a commit.  Note that this
+   is not only for adding new files.  Even modified files must be
+   added to the set of changes about to be committed.  The "git status"
+   command gives you a summary of what is included so far for the
+   next commit.  When done you should use the 'git commit' command to
+   make it real.
+
+   Note: don't forget to 'add' a file again if you modified it after the
+   first 'add' and before 'commit'. Otherwise only the previous added
+   state of that file will be committed. This is because git tracks
+   content, so what you're really 'add'ing to the commit is the *content*
+   of the file in the state it is in when you 'add' it.
+
+2) By using 'git commit -a' directly
+
+   This is a quick way to automatically 'add' the content from all files
+   that were modified since the previous commit, and perform the actual
+   commit without having to separately 'add' them beforehand.  This will
+   not add content from new files i.e. files that were never added before.
+   Those files still have to be added explicitly before performing a
+   commit.
+
+But here's a twist. If you do 'git commit <file1> <file2> ...' then only
+the  changes belonging to those explicitly specified files will be
+committed, entirely bypassing the current "added" changes. Those "added"
+changes will still remain available for a subsequent commit though.
+
+There is a twist about that twist: if you do 'git commit -i <file>...'
+then the commit will consider changes to those specified files _including_
+all "added" changes so far.
+
+But for instance it is best to only remember 'git add' + 'git commit'
+and/or 'git commit -a'.
+
+No special command is required when removing a file; just remove it,
+then tell `commit` about the file as usual.
+
+Viewing the changelog
+---------------------
 
 At any point you can view the history of your changes using
 
diff --git a/builtin-add.c b/builtin-add.c
index febb75e..b3f9206 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -94,9 +94,6 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 
 	newfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1);
 
-	if (read_cache() < 0)
-		die("index file corrupt");
-
 	for (i = 1; i < argc; i++) {
 		const char *arg = argv[i];
 
@@ -131,6 +128,9 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 		return 0;
 	}
 
+	if (read_cache() < 0)
+		die("index file corrupt");
+
 	for (i = 0; i < dir.nr; i++)
 		add_file_to_index(dir.entries[i]->name, verbose);
 
diff --git a/wt-status.c b/wt-status.c
index de1be5b..4b8b570 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -163,7 +163,7 @@ static void wt_status_print_changed_cb(struct diff_queue_struct *q,
 	int i;
 	if (q->nr)
 		wt_status_print_header("Changed but not updated",
-				"use git-update-index to mark for commit");
+				"use git-add on files to include for commit");
 	for (i = 0; i < q->nr; i++)
 		wt_status_print_filepair(WT_STATUS_CHANGED, q->queue[i]);

^ permalink raw reply related

* Some thoughts on resolving conflicts
From: Carl Worth @ 2006-12-01 20:03 UTC (permalink / raw)
  To: git
In-Reply-To: <87slfzfri7.wl%cworth@cworth.org>

[-- Attachment #1: Type: text/plain, Size: 7482 bytes --]

On Fri, 01 Dec 2006 09:36:00 -0800, Carl Worth wrote:
> To finish off, I'd like to propose descriptions of the commands to
> allow the user to use the "without staging" commands as a complete set
> while being able to easily ignore any of the staging capabilities.
> This does trigger a need for a semantic change in the "add"
> command. Here are the proposed descriptions:

By the way, back when we used to call it the "index" one of the things
that was often mentioned as a reason not to "hide the index" is that
the index ends up being so important during the process of resolving a
merge.

This is extremely true, and this is where git really starts to
shine. I've seen people get really put off by the index when they
first encounter "commit -a" or a messages instructing them to
"update-index" something. But, if people are properly presented with
what git offers for helping with conflict resolution then I think they
will fall in love with it.

But I think "hide the index" vs. "celebrate the index" frames the
debate entirely wrong. It's not a matter of "working tree" vs. "index"
being the king. The king is what the user wants to accomplish and what
does git offer to help with that.

So, for example, in the case of conflict resolution, what git offers
in an iterative process involving:

	git diff	Shows what still needs to be resolved

	git resolve	Indicate to git that conflicts are resolved in
			the specified files

(Yes, I'm assuming a future "resolve" synonym for update-index here)
And finally, "git commit" when complete. This is a fantastic sequence
since it fits what the user wants to do and helps the user do it, (and
the incremental nature of it is helpful for large conflicts).

Note that I don't think it's important whether the final "git commit"
executes a "commit -a" or a mode traditional commit-the-index. It
would be exceedingly rare for someone to want to make a partial,
staged commit during conflict resolution. So I think that special case
can be entirely ignored when considering the user-interface.

So git provides tools well suited to the job here. One thing it
doesn't do well is to advertise them to the user. It would probably be
helpful to print some small section of advice and guidance when the
conflict happens. Right now, git spews a lot of scary internal state
that definitely gives the impression of things going wrong, and
doesn't tell the user much about what to do. It would be nice to say
something more along the lines of "A conflict occurred during the
merge attempt. That's nothing to worry about---it happens
sometimes. And here are some tools that git offers to help you fix
things up:..."

And there are other lovely things that git provides, such as:

	git log -p --merge	Shows commits that contributed to this conflict

	git diff --ours		Show changes in working tree compared
				to our latest commit for unresolved files

	git diff --theirs	Show changes in working tree compared
				to the commit being merged in for
				unresolved files

To tell the truth, I hadn't really played with "diff --ours" and "diff
--theirs" much before. They're right handy! I can't find any
documentation for them, (it might exist somewhere deep in the plumbing
documentation but I can't find it). It would be great to have
examples in the "git diff" page showing these off, and maybe some
hints in the message that comes from the conflicted merge.

So the above commands are wildly useful. But there not useful because
"the index is an essential part of git", they're useful because they
help the user get information related to what the user is doing.

One command that I didn't find in my experimentation was how to see
the multi-parent diff after resolving the conflict. I found that I can
do a single-parent thing with:

	git diff --cached	Show changes in staging area compared
				to our latest commit.

But I didn't figure out how to get the multi-parent thing there
yet. After I make the commit object I _can_ see the result I want with
"git show", but it would be nice to be able to see that before the
commit.

Surely there's a command-line option somewhere that does this, with a
name like -cc or -C or something, but it's something that I would
argue should acquire a different name---that is, if I were doing
conflict resolution often. As it stands now, I rarely have any
conflicts to resolve, so any user-interface warts that git has here
haven't rubbed me the wrong way yet. Other than the conflict spew
which gives the impression of "Git tried (multiple ways) and failed to
merge this mess. You're on your own now."

-Carl

PS. Here's the example I just used to experiment with conflict
resolution. It's something like this that would be nice to have in
something like "git tutorial conflict-resolution" which would run the
following sequence of commands for the user and then invite the user
to play with things like "git diff --ours" and "git diff --theirs".

The commands below look really ugly, so we definitely don't want the
tutorial reader to ever have to go through all this
state-creation. But the end result---what the user sees in "git diff"
is so intuitive that it would be wonderful to have this kind of thing
readily available at the command-line.

A more ambitious example might setup conflict in multiple files to
teach the incremental nature of using "git diff" and "git resolve"
together.

mkdir git-tutorial-conflict-resolution
cd git-tutorial-conflict-resolution
git init-db
echo 'vvv Context paragraph 1 vvv
This is a paragraph that exists for context.
It will be unmodified in both branches.
^^^ Context paragraph 1 ^^^

This is a paragraph that I will modify in master
and delete in other.

vvv Context paragraph 2 vvv
This is a second paragraph that exists for context.
It too, will be unmodified in both branches.
^^^ Context paragraph 2 ^^^

This is a paragraph that I will delete in master
and modify in other.

vvv Context paragraph 3 vvv
This is the third paragraph that exists for context.
Again, it will be unmodified in both branches.
^^^ Context paragraph 3 ^^^

This is a paragraph that I will modify in two
different ways in master and other.
' > file
git add file
git commit -m "add file"
git branch other
echo 'vvv Context paragraph 1 vvv
This is a paragraph that exists for context.
It will be unmodified in both branches.
^^^ Context paragraph 1 ^^^

This is a paragraph that I have modified
in master.

vvv Context paragraph 2 vvv
This is a second paragraph that exists for context.
It too, will be unmodified in both branches.
^^^ Context paragraph 2 ^^^

vvv Context paragraph 3 vvv
This is the third paragraph that exists for context.
Again, it will be unmodified in both branches.
^^^ Context paragraph 3 ^^^

This is a paragraph that I have modified
in master.
' > file
git commit -a -m "master modifications"
git checkout other
echo 'vvv Context paragraph 1 vvv
This is a paragraph that exists for context.
It will be unmodified in both branches.
^^^ Context paragraph 1 ^^^

vvv Context paragraph 2 vvv
This is a second paragraph that exists for context.
It too, will be unmodified in both branches.
^^^ Context paragraph 2 ^^^

This is a paragraph that I have modified
in other.

vvv Context paragraph 3 vvv
This is the third paragraph that exists for context.
Again, it will be unmodified in both branches.
^^^ Context paragraph 3 ^^^

This is a paragraph that I have modified
in other
' > file
git commit -a -m "other modifications"
git checkout master
git pull . other

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: selective git-update-index per diff(1) chunks
From: Johannes Schindelin @ 2006-12-01 19:42 UTC (permalink / raw)
  To: Anand Kumria; +Cc: git
In-Reply-To: <ekpm6i$s35$1@sea.gmane.org>

Hi,

On Fri, 1 Dec 2006, Anand Kumria wrote:

> On Fri, 01 Dec 2006 03:38:13 -0800, Junio C Hamano wrote:
> 
> > Peter Baumann <Peter.B.Baumann@stud.informatik.uni-erlangen.de>
> > writes:
> > 
> >> I don't think it belongs in the plumbing, the git-update-index but I
> >> think something like this would be very usefull.
> >>
> >> AFAIR darcs has this functionality. It selectively ask for each hunk if
> >> it should be commited. This would be awfull to have in git.
> > 
> > I concur, on both counts.  My own now-defunct Porcelain had the
> > darcs style interactive hunk selection because it felt so
> > useful (and sometimes it was).
> 
> Is there a good receipe on how to do this? Everytime I do it, I try a
> different method; since I'm testing out my understanding of things.
> 
> It'd nice to have some of these "advanced receipes" that people often do
> noted down somewhere.

Can't say anything about advanced recipes, but I use a poor-man's 
workflow:

$ git diff > a1.patch
$ vi a1.patch
  <edit out what I want to _keep_>
$ git apply -R < a1.patch
  <test & commit>
$ git apply < a1.patch

Of course, you could write a little wrapper around it, even one which asks 
you which hunks you want to edit out. Should not be that hard...

Note that this is independent of the SCM you are using.

Ciao,
Dscho

^ permalink raw reply

* Re: [RFC] Submodules in GIT
From: Martin Waitz @ 2006-12-01 19:38 UTC (permalink / raw)
  To: Andy Parkins; +Cc: git, sf
In-Reply-To: <200612011917.19252.andyparkins@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 876 bytes --]

hoi :)

On Fri, Dec 01, 2006 at 07:17:17PM +0000, Andy Parkins wrote:
> In fact, why should the submodule commits be even visible in the
> supermodule?  That tree->submodule commit is sufficient; there isn't
> any need to view submodule history in the supermodule.

Well, but there is a need for a common object traversal.
You need that when sending all objects between two supermodule versions
and also when you determine which objects are still reachable.

The easiest way to implement the common object traversal is to have all
objects in one object repository.

It may be possible to use two object stores and still do the common
object traversal but I do not think that gives you any benefits.
You still don't have a totally separated repository then, because
you can't do a reachability analysis in the submodule repository alone.

-- 
Martin Waitz

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [RFC] Submodules in GIT
From: Andy Parkins @ 2006-12-01 19:17 UTC (permalink / raw)
  To: git, sf; +Cc: Martin Waitz
In-Reply-To: <45706758.2020907@b-i-t.de>

On Friday 2006, December 01 17:33, Stephan Feder wrote:

> 1. A submodule is stored as a commit id in a tree object.
>
> 2. Every object that is reachable from the submodule's commit are
> reachable from the supermodule's repository.

I'm still not convinced about 2.  Why should any of the submodule commits be 
in the supermodule repository?  I know that is what you've implemented, but 
it still feels like too much of a blending of the submodule into the 
supermodule.

In fact, why should the submodule commits be even visible in the supermodule?  
That tree->submodule commit is sufficient; there isn't any need to view 
submodule history in the supermodule.



Andy

-- 
Dr Andrew Parkins, M Eng (Hons), AMIEE

^ permalink raw reply

* Re: Garbled man pages (.sp instead of newline)
From: Jonas Fonseca @ 2006-12-01 19:01 UTC (permalink / raw)
  To: Carl Worth; +Cc: git
In-Reply-To: <87r6vjfqij.wl%cworth@cworth.org>

Carl Worth <cworth@cworth.org> wrote Fri, Dec 01, 2006:
> I can see a lot of things that I think I could improve in the
> documentation, but when I tried to build them, I'm getting broken man
> pages as a result. For example with "man git" I now see:
> 
>        Git is a fast, scalable, distributed revision control system with an unusually rich
>        command set that provides both high-level operations and full access to
>        internals..sp See this [1]tutorial to get started, then see [2]Everyday Git for a
>        useful minimum set of commands, and "man git-commandname" for documentation of each
>        command. CVS users may also want to read [3]CVS migration..sp The COMMAND is either
>        a name of a Git command (see below) or an alias as defined in the configuration
>        file (see git-repo-config(1))..sp
> 
> I appear to be using asciidoc 7.1.2. Does anyone here know what's
> causing the above and how to fix it?

The problem is that a newline is not inserted before the ".sp".  I (and
apparently a lot of other people on #git) thought it was just something
broken by the system. It appears that the DocBook XSL files got broken
between 1.69.0 and 1.69.1, but it appears to have been fixed upstream (I
didn't try it by from looking at the xsl/manpages/block.xsl file it
seems to insert a newline again before inserting a ".sp")

Git already has a custom XSL file to handle callouts so this might be
the right place to insert a workaround for this although I don't know if
it breaks systems that do not have this problem. The patch that I have
included is based on what I plan to add to tig. It would be great to
hear if it breaks manpages build on systems that do not have this ".sp"
problem.

I also have another small fix to insert an empty line after a code
block. Currently, the following paragraph will immediately follow the
code block which hurts readability a bit.

BTW, it might make sense to rename callouts.xsl to manpage.xsl if
something like this and the other fix I mentioned is acceptable.

diff --git a/Documentation/callouts.xsl b/Documentation/callouts.xsl
index ad03755..d016b3b 100644
--- a/Documentation/callouts.xsl
+++ b/Documentation/callouts.xsl
@@ -13,4 +13,44 @@
 	<xsl:apply-templates/>
 	<xsl:text>.br&#10;</xsl:text>
 </xsl:template>
+<xsl:template match="simpara">
+  <xsl:variable name="content">
+    <xsl:apply-templates/>
+  </xsl:variable>
+  <xsl:value-of select="normalize-space($content)"/>
+  <xsl:text>&#10;</xsl:text>
+  <xsl:text>.sp&#10;</xsl:text>
+</xsl:template>
+
+<xsl:template match="address|literallayout|programlisting|screen|synopsis">
+  <!-- * Yes, address and synopsis are verbatim environments. -->
+
+  <xsl:choose>
+    <!-- * Check to see if this verbatim item is within a parent element that -->
+    <!-- * allows mixed content. -->
+    <!-- * -->
+    <!-- * If it is within a mixed-content parent, then a line space is -->
+    <!-- * already added before it by the mixed-block template, so we don't -->
+    <!-- * need to add one here. -->
+    <!-- * -->
+    <!-- * If it is not within a mixed-content parent, then we need to add a -->
+    <!-- * line space before it. -->
+    <xsl:when test="parent::caption|parent::entry|parent::para|
+                    parent::td|parent::th" /> <!-- do nothing -->
+    <xsl:otherwise>
+      <xsl:text>&#10;</xsl:text>
+      <xsl:text>.sp&#10;</xsl:text>
+    </xsl:otherwise>
+  </xsl:choose>
+  <xsl:text>.nf&#10;</xsl:text>
+  <xsl:apply-templates/>
+  <xsl:text>&#10;</xsl:text>
+  <xsl:text>.fi&#10;</xsl:text>
+  <!-- * if first following sibling node of this verbatim -->
+  <!-- * environment is a text node, output a line of space before it -->
+  <xsl:if test="following-sibling::node()[1][name(.) = '']">
+    <xsl:text>&#10;</xsl:text>
+    <xsl:text>.sp&#10;</xsl:text>
+  </xsl:if>
+</xsl:template>
 </xsl:stylesheet>

-- 

^ permalink raw reply related

* Re: [RFC] Submodules in GIT
From: Martin Waitz @ 2006-12-01 18:51 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: sf, git
In-Reply-To: <45706F8C.3070000@op5.se>

[-- Attachment #1: Type: text/plain, Size: 385 bytes --]

hoi :)

On Fri, Dec 01, 2006 at 07:08:12PM +0100, Andreas Ericsson wrote:
> You're assuming the super- and sub-module will share HEAD, or at least 
> ODB, I think.

not HEAD, only ODB.

> I'm not convinced this is necessary. Convince me. I'll go 
> drink bear and get some dancing done while you're at it ;-)

Get me a beer and I will convince you :-)

-- 
Martin Waitz

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [RFC] Submodules in GIT
From: Martin Waitz @ 2006-12-01 18:48 UTC (permalink / raw)
  To: Stephan Feder; +Cc: git
In-Reply-To: <45706758.2020907@b-i-t.de>

[-- Attachment #1: Type: text/plain, Size: 3581 bytes --]

On Fri, Dec 01, 2006 at 06:33:12PM +0100, Stephan Feder wrote:
> We are in agreement about two fundamental parts of the implementation 
> and their meaning:
> 
> 1. A submodule is stored as a commit id in a tree object.
> 
> 2. Every object that is reachable from the submodule's commit are 
> reachable from the supermodule's repository.

Correct.

> >>For example, git has the subproject xdiff. If git had been able to work 
> >>with subprojects as I envision, and if xdiff had been published as a git 
> >>repository (not necessarily subproject enabled), it could have been 
> >>pulled in git's subdirectory xdiff as a subproject.
> >
> >This could have been done if submodule support would have been available
> >at the time xdiff was introduced, yes.
> >
> >>There would not have been a separate branch or even repository for
> >>xdiff in the git repository.
> >
> >What separate branch or repository are you talking about?
> 
> That's it: There is no need for a separate branch or repository. If you 
> have the subproject's commit in the superproject's object database (and 
> we really have that, see 1. and 2. above), why do you _have to_ store it 
> elsewhere?

Let's see if I understand you correctly:

You don't want to create an additional .git directory for the submodule
and just handle everything with one toplevel .git repository for the
whole project.
Without the .git directory, you of course do not have refs/heads inside
the submodule.

So this is a different user-interface approach to submodules when
compared to my approach.  But the basis is the same and both could
inter-operate.

Now your submodule is no longer seen as an independent git repository
and I think this would cause problems when you want to push/pull between
the submodule and its upstream repository.
No technical problems, but UI-problems because now your submodule is
handled completly different to a "normal" repository.


> >Yes, but if it would have been integrated as a submodule it obviously
> >would have been committed to the xdiff submodule inside the git
> >repository.
> 
> No. The xdiff submodule would only exist as part of the git repository. 

But you could still call the "xdiff" part of the git repository a
submodule.  And then changes to the xdiff directory result in a new
submodule commit, even when there is no direct reference to it.
So you'd still "commit to the xdiff submodule".

> You could, f.e., access the xdiff commit in git HEAD as HEAD:xdiff// 
> (again my proposed syntax). HEAD:xdiff//~2:xemit.c would give you the 
> grandparent of xemit.c in the xdiff submodule.

git-cat-file commit HEAD:xdiff already works out of the box (even
cat-file tree to get the submodule tree).  But up to now revision
parsing follows the file name only once.

What about just separating things with "/"?

commit HEAD
tree   HEAD/
blob   HEAD/Makefile
commit HEAD/xdiff
tree   HEAD/xdiff/
blob   HEAD/xdiff~2/xemit.c

this may add some confusion when used with hierarchical branches, but
it's still unique:

	refs/heads/master/xdiff/xemit.c

Just use as many path components until a matching reference is found,
then start peeling.
Or just use / between super and submodule:

	refs/heads/master:xdiff/xemit.c

I think this is easier to read then

	refs/heads/master:xdiff//:xemit.c


> If you mean the submodule repository created by init-module I 
> understand. But why create this "helper repository at all"?

Because it helps "normal" git operations ;-)

-- 
Martin Waitz

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".
From: Shawn Pearce @ 2006-12-01 18:27 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <eknj33$q2r$1@sea.gmane.org>

Jakub Narebski <jnareb@gmail.com> wrote:
> Robert Shearman wrote:
> 
> > Having the index exposed for even simple operations means that the user 
> > has to initially learn three states instead of two. The worst thing 
> > about the index is that it is a limbo state. The committed content is in 
> > the history and can be viewed by gitk (and other tools that the user 
> > will be introduced to later) and the working tree is exactly what the 
> > user sees in their editor. Having a hidden state isn't very good from an 
> > HCI point of view.
> 
> Index is accessible, just like committed contents. The fact that gitk, qgit,
> git-gui doesn't display state of index is their limitation.

Actually git-gui shows the index, but not quite as well as diff
and friends would.

But based on this thread I had a major realization: git-gui is
totally wrong in how it displays files (and therefore gitool is
too!).  I'm going to rewrite that part of git-gui's UI, hopefully
early next week.

Linus is right: To deny the index is to deny git itself.  Trying to
hide part of the index in git-gui is just wrong and makes things
like merge conflict resolutions harder, not easier.

-- 

^ permalink raw reply

* Re: [RFC] Submodules in GIT
From: Andreas Ericsson @ 2006-12-01 18:08 UTC (permalink / raw)
  To: Martin Waitz; +Cc: sf, git
In-Reply-To: <20061201165708.GE18810@admingilde.org>



Martin Waitz wrote:
> On Fri, Dec 01, 2006 at 05:38:44PM +0100, Andreas Ericsson wrote:
>>> But if the supermodule contains changes to the submodule, you still
>>> have to change the submodule.  And this implies changing the submodule
>>> HEAD or some branch.
>>>
>> Not really. I fail to see why HEAD needs to be changed so long as the 
>> commit is in the submodule's odb.
> 
> Because I want the submodule to act as a normal git repository.
> Please note that I also voted against changing HEAD directly, but that
> the new commit which came from the supermodule is just stored in one
> branch of the submodule, as part of the supermodule checkout.
> 

You're assuming the super- and sub-module will share HEAD, or at least 
ODB, I think. I'm not convinced this is necessary. Convince me. I'll go 
drink bear and get some dancing done while you're at it ;-)

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se

^ permalink raw reply

* Re: [RFC] Submodules in GIT
From: Andreas Ericsson @ 2006-12-01 18:06 UTC (permalink / raw)
  To: sf; +Cc: git, Martin Waitz
In-Reply-To: <457061A7.2000102@b-i-t.de>

sf wrote:
> 
> That is one of the points Martin Waitz and I are discussing.
> 
> If I understand you correctly you cannot make any changes to the 
> submodules code _in the supermodule's repository_, no bugfixes, no 
> extensions, no adaptions, nothing. Do you mean that?
> 
> That would be a third alternative. In my opinion the usefulness of 
> submodules would be unnecessarily restricted if it comes to the choice 
> of either using the code from upstream as is or do not use submodules at 
> all. What is the point of the restriction?
> 

That depends on your definition of submodule. In my eyes, a submodule is 
a separate repo that can be committed to separately (and generally also 
built separately), although it's usually built into something else. I'm 
imagining most submodules will contain only library code and its testing 
routines.

Insofar as I've envisioned submodules, it's a separate git repo where 
you simply record a certain snapshot of the sub-repo with a commit in 
the super-module, like so:

$ git commit ssl-functions/*.[ch] openssl -m "Upgraded openssl with 
necessary changes to core code"

(yes, I know it's horrid to use -m to commit, and I daily advocate 
against it where I work, but you get the idea, I'm sure)

Isn't this how it's supposed to work? Enlighten me, and please remember 
that I'm drunk atm, so make it obvious ;-)

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se

^ permalink raw reply

* Garbled man pages (.sp instead of newline)
From: Carl Worth @ 2006-12-01 17:57 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 960 bytes --]

I've spent too much time just "talking" on this list and I'd like to
start "doing" more.

I can see a lot of things that I think I could improve in the
documentation, but when I tried to build them, I'm getting broken man
pages as a result. For example with "man git" I now see:

       Git is a fast, scalable, distributed revision control system with an unusually rich
       command set that provides both high-level operations and full access to
       internals..sp See this [1]tutorial to get started, then see [2]Everyday Git for a
       useful minimum set of commands, and "man git-commandname" for documentation of each
       command. CVS users may also want to read [3]CVS migration..sp The COMMAND is either
       a name of a Git command (see below) or an alias as defined in the configuration
       file (see git-repo-config(1))..sp

I appear to be using asciidoc 7.1.2. Does anyone here know what's
causing the above and how to fix it?

-Carl

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* [RFC] Introduce "git stage" (along with some heresy)
From: Carl Worth @ 2006-12-01 17:36 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 9354 bytes --]

[This message, (yes,another long one from me), proposes 3 changes. The
first should be uncontroversial I think, while the second and third
are clear heresy, (and the second would require some amount of
re-training or re-configuration by existing git user). Pick and choose
as you see fit. I don't think they actually depend on each other,
though I'll present them here as parts of a whole.]

Change #1: Add "git stage" command, use "--staged" instead of "--index"
=======================================================================
If we're going to start describing the index as a "staging area" let's
make the command set reflect that as well. I propose a new "git stage"
command that is intended for human use when wanting to do a staged
commit.

Then, a few other commands that currently have --index or --cached
arguments could switch to --staged as well.

With this change here is a summary of some of the primary git commands
(that are relevant to the current discussion):

add		Shove a file's contents into git's staging area

stage		Shove a file's contents into git's staging area

rm		Remove a file from git's staging area

diff		Show what's changed in working tree compared to
		staging area

diff --staged	Show what's changed in staging area compared to latest
		commit

commit		Create a new commit from the contents of the staging area

commit -a	Update the contents of all files in the staging area,
		and create a new commit from the new staging area

commit files...	Create a new commit that differs from the latest
		commit only in files... (which get new content from
		the current working tree). Staged content of other
		files (if any) will not be committed.

I hope that so far (in this email) I haven't said anything very
contentious. This is basically just a summary of the existing behavior
with things like "update-index" and "--cached" changed to "stage" and
"--staged".

The introduction of this new "stage" command would be a very minor
change. If you're not particularly picky about names, it might be seen
as having no impact at all, (or even slightly negative since "add" and
"stage" could be considered equivalent). If you are picky about names
you might consider it slightly better to "add" when adding a new file
and to "stage" when you want to put some content into the staging area.

OK, so now let me start in with my heresy[*].

To start with I'd like to group the above command into two groups such
that one can be understood without a need to understand the purpose of
the staging area. Note: the goal here is not to lie about the staging
area. It will still be mentioned in the documentation for any command
that needs to mention it, but in a way that a user can easily ignore
those portions at first. So the grouping is:

Without staging
---------------
add
rm
diff
commit -a
commit files...

With staging
------------
stage
diff --staged
commit

So far, that's just a re-grouping. No names or semantics have been
changed.

Change #2: Make a staged commit an explicit act
===============================================
The "-a" stands out to me here as the only command-line option needed
in the first list, and the only command in the second list that
performs a staged operation by default. So change number to is to
redefine "commit" to mean what "commit -a" meant before and to require
a new command-line option for staged committing, (the best naming I
have so far is "commit --staged" with a shortcut of "commit -i"---the
mismatch of "'i' as short for --staged" is a bit unlovely I admit).

Here's what we have after change #2:

Without staging
---------------
add
rm
diff
commit
commit files...

With staging
------------
stage
diff --staged
commit --staged (or "commit -i")

Change #3: Change "add" to not stage any content
================================================
To finish off, I'd like to propose descriptions of the commands to
allow the user to use the "without staging" commands as a complete set
while being able to easily ignore any of the staging capabilities.
This does trigger a need for a semantic change in the "add"
command. Here are the proposed descriptions:

Without staging
---------------
add		Add a file to be managed by git

rm		Remove a file to no longer be managed by git

diff		Show the changes in the working tree compared to the
		latest commit, (or compared to staged content, if any)

commit		Commit the current state of all git-managed files

commit files...	Commit the current state of the specified files

With staging
------------
stage		Shove the current contents of the specified files into
		git's staging area

diff --staged	Show the changes in the staging area compared to the
		latest commit

commit --staged	Commit the state of the current staging area
commit -i

To make the above work, I think Daniel's suggestion of making "add"
put 0{40} into the staging area should work just fine. I know that
Linus has religious objections to these proposed new semantics of "git
add". One response there is to just consider "add" to be a mud-pit
command for people to wallow in that really want it, (like Linus'
proposed "ci" command). If you don't want to be in that mud-pit, then
just use my "stage" command along with "commit -i", (or with "commit"
and some configuration option, or with "commit" and a rejection to my
change #2).

Another response is that these new semantics for "add" really aren't
any worse than other existing things in git, (for example, "git rm"
isn't just updating file content into the index---because it even
leaves the file around by default). [Actually, the fact that "git rm"
doesn't delete the file by default is a bug (and it's my bug). I think
the right thing is that "git rm" should be defined as always deleting
the file from the working tree, and that it should be fixed to fail if
the file if the file is dirty, (unless -f is passed)].

Other examples of the current semantics of git commands being just as
"evil", (I would argue "usable" instead), are below.

I think that here, finally, I've made my proposal as clearly and
consistently as I can. I think the above would only improve git, (by
making it easier to use by new people, while still providing a
consistent model and a way to easily learn everything git has to
offer). Change #2 would be the hardest pill to swallow since it would
mean some change in the habits of existing users, (the other changes
could largely be blissfully ignored by trained git users I
think). This difficulty could be softened with a configuration option
something like core.commitStagedByDefault, or this one change could be
rejected.

-Carl

[*] I say heresy, but I think all the talk about "inconsistency" and
"dishonesty" in the proposals I've been making are really
misplaced. The easiest way to see that is to apply the same arguments
to existing commands in git and see that they are already inconsistent
and dishonest.

Inconsistency
-------------
If the consistent model is "'commit' commits the contents of the
staging area" then what in the world is happening in the case of
"commit files..."? There's really no way to describe that operation in
terms of the staging area, because it simply ignores it. The closest
you could get is to describe the internal implementation in detail:

commit files... Creates a temporary staging area from the latest
		commit, shoves the content of the named files into
		that temporary staging area, creates a new commit from
		that and then does [something] to the original staging
		area.

I (obviously) botched that. Somebody could write an actual, correct
technical description. But you know what? It would be totally
useless. It's really hard to describe what the current command does in
terms of the staging area and nobody would care anyway. It wouldn't
help anybody use the thing. The fact that all commit operations _do_
involve a staging area at some deep point in the implementation is
totally irrelevant to the fact that what "commit files..." does do
_is_ desirable, and is not hard to explain at a conceptual level. What
the current documentation has is:

	"Commit only the files specified on the command line."

This documentation doesn't say _anything_ about the content coming
from the working tree rather than the index. But that's _obviously_
the correct place for the content to come from, and that's what's
implemented.

Dishonesty
----------
The argument here is that some "easier to use" commands lie to the
user, giving them an incorrect idea of what's really happening, and
that this will create barriers to later understanding. I think the
same argument could be applied to say that there's no reason to have
"add", "rm", "resolve", and "update-index" (or "stage"). These
commands are all doing the same thing at a technical level, so why lie
to the user and let the user think they are doing something different?
My reply is that this isn't a lie, but it's providing names for the
user that match the operations that the user is conceptually
doing. That's called "providing a usable interface". If the user goes
on to learn the internals and discovers that these are all wrappers
around some shared core command, then the user can appreciate that
elegance of implementation. But forcing everyone to _use_ one command
for these conceptually separate arguments would be a mistake from the
point-of-view of usability.

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [RFC] Submodules in GIT
From: Stephan Feder @ 2006-12-01 17:33 UTC (permalink / raw)
  To: Martin Waitz; +Cc: git
In-Reply-To: <20061201165418.GD18810@admingilde.org>

Martin Waitz wrote:
> hoi :)
> 
> On Fri, Dec 01, 2006 at 04:47:47PM +0100, Stephan Feder wrote:
>> No so different. The way I see it is that "I" (meaning with submodules 
>> implemented as I proposed) could pull regularly from "your" repositories 
>> (implemented as you proposed) and work with the result (including 
>> submodules). Could you do the same?
> 
> Sorry, but with all that many people proposing things I am a bit lost
> now.  Sometimes I thought you want exactly the same thing as I do,
> sometimes I think we are talking in totally different directions.

We are in agreement about two fundamental parts of the implementation 
and their meaning:

1. A submodule is stored as a commit id in a tree object.

2. Every object that is reachable from the submodule's commit are 
reachable from the supermodule's repository.

Please confirm.

We now argue about how to work with that repository _object_ model.

>> >For me a submodule is responsible for everything in or below a certain
>> >directory.  So by definition when you change something in this
>> >directory, you have to change it in the submodule.
>> 
>> But you do not consider the case where you cannot change the submodule 
>> because you do not own it.
> 
> I do not understand you here.
> The submodule is part of the supermodule, and the one who sets up the
> repository owns the whole thing, including all submodules, just like all
> the files which are part of the project.

If you mean by "owns the whole thing" what I stated above in 2. the we 
agree.

> If you mean the upstream repository of the submodule, then yes, this is
> of course completely separated from the submodule and may be owned by
> someone else.  Consequently, this upstream repository of course does not
> need to change when someone introduces changes in the supermodule.

I think we still agree.

>> For example, git has the subproject xdiff. If git had been able to work 
>> with subprojects as I envision, and if xdiff had been published as a git 
>> repository (not necessarily subproject enabled), it could have been 
>> pulled in git's subdirectory xdiff as a subproject.
> 
> This could have been done if submodule support would have been available
> at the time xdiff was introduced, yes.
> 
>> There would not have been a separate branch or even repository for
>> xdiff in the git repository.
> 
> What separate branch or repository are you talking about?

That's it: There is no need for a separate branch or repository. If you 
have the subproject's commit in the superproject's object database (and 
we really have that, see 1. and 2. above), why do you _have to_ store it 
elsewhere?

>> All changes to xdiff in git could have been committed to the git 
>> repository only.
> 
> Yes, but if it would have been integrated as a submodule it obviously
> would have been committed to the xdiff submodule inside the git
> repository.

No. The xdiff submodule would only exist as part of the git repository. 
You could, f.e., access the xdiff commit in git HEAD as HEAD:xdiff// 
(again my proposed syntax). HEAD:xdiff//~2:xemit.c would give you the 
grandparent of xemit.c in the xdiff submodule. And so on. You can even 
have submodules that have themselves submodules.

> So the changes are really part of the git repository, but you could go
> to the "git/xdiff" directory and only see the changes in the submodule,
> without the normal supermodule history.

See above.

>> Independently, they could have been published to upstream and be put
>> into the xdiff repository by its author.  But the last part is what
>> only the owner of the xdiff repository is able to decide.
> 
> Of course, everything still works like normal git repositories.

OK.

>> >You can't change the submodule contents in the supermodule without also
>> >changing the submodule.
>> >This is just like you can't commit a change to a file without also
>> >changing the file.
>> 
>> There is a difference. I would say: If you commit a change to a file in 
>> one branch, it need not be changed in all branches.
> 
> But you need to change _at_least_ one branch.
> Otherwise you cannot commit to a branch.

But only the supermodule's branch.

> So if you change something in a submodule, you have to change one branch
> in the submodule.

No.

> If you call git-checkout in the supermodule this will result in
> something like a git-reset in the submodule.

If you mean the submodule repository created by init-module I 
understand. But why create this "helper repository at all"?

>> >No, this is the benefit you get by introducing submodules.
>> >Why would you want to introduce a submodule when it is not linked to the
>> >supermodule?
>> 
>> Because the submodule must be independent of the supermodule.
>> 
>> I see where you are coming from. You have one project that is divided 
>> into subprojects but the subprojects themselves are not independent.
>> 
>> What I would like to solve is the followng: You have a project X, an 
>> this project is made part of two other projects Y and Z (as a submodule 
>> or subproject or whatever you want to call it). The project X need not, 
>> must not or cannot care that it was made a subproject. But in projects Y 
>> and Z, you must be able to bugfix or extend or modify the code of 
>> projectX, and you must be able to push and pull changes between all 
>> three projects (of course we are only talking about the code part of 
>> project X).
> 
> Of course.
> 
> So if you wanted to check out everything, you could have something like
> ~/src/X, ~/src/Y/X, and ~/src/Z/X.
> All of these would be GIT repositories, all of them have their
> independent branches.
> 
> What I am saying is just that if you update Y, and the new Y contains an
> updated version of X, then ~/src/Y/X/.git/refs/heads/master will be
> changed by the pull, resulting in the new version of X being checked out
> in ~/src/Y/X (alongside all the other updates inside ~/src/Y).
> This of course is independend from ~/src/X or  ~/src/Z/X.
> 
>> Do you see where your solution makes that impossible, and that with more 
>> changes to the repository layout?
> 
> No ;-)
> 

Sorry, have to leave for home so I must leave that uncommented. 
Hopefully I can join in during the weekend.

Regards


^ permalink raw reply

* Re: [RFC] Submodules in GIT
From: Martin Waitz @ 2006-12-01 17:14 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Andreas Ericsson, sf, git
In-Reply-To: <Pine.LNX.4.64.0612010844380.3695@woody.osdl.org>

[-- Attachment #1: Type: text/plain, Size: 1606 bytes --]

hoi :)

On Fri, Dec 01, 2006 at 08:49:20AM -0800, Linus Torvalds wrote:
> Think of it this way: one common use for submodules is really to just 
> (occasionally) track somebody elses code. The submodule should be a 
> totally pristine copy from somebody else (ie it might be the "intel driver 
> for X.org" submodule, maintained within intel), and the supermodule just 
> refers to it indirectly (ie the supermodule might be the "Fedora Core X 
> group" which contains all the different drivers from different people).

Yes, but it is not only about tracking, also about distributing
submodules.

One Fedora X developer fixes a bug in the intel driver, commits that to
the submodule and then updates the supermodule to the new version (by
calling "git-update-index drivers/intel && git-commit" or something).  Then
another Feora X developer updates his X repository.  By pulling the
supermodule he also gets a new version of the submodule.
And this new version of the submodule is stored in a branch which can be
accessed by the submodule.

> A supermodule can never "contain changes" to a submodule.

The supermodule always contains _the_entire_ submodule with its complete
history, so it also does contain changes.  But it does not per-se
contain changes, only indirectly (i.e. the commits in the submodule are
not part of the supermodule commit chain).

> A supermodule would always just point to the submodule, and not have
> any changes what-so-ever of its own. The submodule is self-sufficient,
> and always contains all its _own_ changes.

Yes.

-- 
Martin Waitz

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [RFC] Submodules in GIT
From: sf @ 2006-12-01 17:08 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Martin Waitz, git
In-Reply-To: <Pine.LNX.4.64.0612010844380.3695@woody.osdl.org>

Linus Torvalds wrote:
...
 > Think of it this way: one common use for submodules is really to just
 > (occasionally) track somebody elses code. The submodule should be a
 > totally pristine copy from somebody else (ie it might be the "intel 
driver
 > for X.org" submodule, maintained within intel), and the supermodule just
 > refers to it indirectly (ie the supermodule might be the "Fedora Core X
 > group" which contains all the different drivers from different people).

Could you please be a little bit more specific about how you would store 
the "pristine copy". There seems to be some agreement to store the 
commit id of the submodule instead of a plain tree id in the 
supermodules tree object, and that all objects that are reachable from 
this commit are made part of the supermodule repository (either fetched 
or via alternates). Do you agree?

...
 > A supermodule can never "contain changes" to a submodule. A supermodule
 > would always just point to the submodule, and not have any changes
 > what-so-ever of its own. The submodule is self-sufficient, and always
 > contains all its _own_ changes.

That is one of the points Martin Waitz and I are discussing.

If I understand you correctly you cannot make any changes to the 
submodules code _in the supermodule's repository_, no bugfixes, no 
extensions, no adaptions, nothing. Do you mean that?

That would be a third alternative. In my opinion the usefulness of 
submodules would be unnecessarily restricted if it comes to the choice 
of either using the code from upstream as is or do not use submodules at 
all. What is the point of the restriction?

Regards


^ permalink raw reply

* Re: [RFC] Submodules in GIT
From: Martin Waitz @ 2006-12-01 16:57 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: sf, git
In-Reply-To: <45705A94.2070509@op5.se>

[-- Attachment #1: Type: text/plain, Size: 652 bytes --]

On Fri, Dec 01, 2006 at 05:38:44PM +0100, Andreas Ericsson wrote:
> >But if the supermodule contains changes to the submodule, you still
> >have to change the submodule.  And this implies changing the submodule
> >HEAD or some branch.
> >
> 
> Not really. I fail to see why HEAD needs to be changed so long as the 
> commit is in the submodule's odb.

Because I want the submodule to act as a normal git repository.
Please note that I also voted against changing HEAD directly, but that
the new commit which came from the supermodule is just stored in one
branch of the submodule, as part of the supermodule checkout.

-- 
Martin Waitz

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [RFC] Submodules in GIT
From: Martin Waitz @ 2006-12-01 16:54 UTC (permalink / raw)
  To: Stephan Feder; +Cc: git
In-Reply-To: <45704EA3.40203@b-i-t.de>

[-- Attachment #1: Type: text/plain, Size: 4870 bytes --]

hoi :)

On Fri, Dec 01, 2006 at 04:47:47PM +0100, Stephan Feder wrote:
> No so different. The way I see it is that "I" (meaning with submodules 
> implemented as I proposed) could pull regularly from "your" repositories 
> (implemented as you proposed) and work with the result (including 
> submodules). Could you do the same?

Sorry, but with all that many people proposing things I am a bit lost
now.  Sometimes I thought you want exactly the same thing as I do,
sometimes I think we are talking in totally different directions.

> >For me a submodule is responsible for everything in or below a certain
> >directory.  So by definition when you change something in this
> >directory, you have to change it in the submodule.
> 
> But you do not consider the case where you cannot change the submodule 
> because you do not own it.

I do not understand you here.
The submodule is part of the supermodule, and the one who sets up the
repository owns the whole thing, including all submodules, just like all
the files which are part of the project.

If you mean the upstream repository of the submodule, then yes, this is
of course completely separated from the submodule and may be owned by
someone else.  Consequently, this upstream repository of course does not
need to change when someone introduces changes in the supermodule.

> For example, git has the subproject xdiff. If git had been able to work 
> with subprojects as I envision, and if xdiff had been published as a git 
> repository (not necessarily subproject enabled), it could have been 
> pulled in git's subdirectory xdiff as a subproject.

This could have been done if submodule support would have been available
at the time xdiff was introduced, yes.

> There would not have been a separate branch or even repository for
> xdiff in the git repository.

What separate branch or repository are you talking about?

> All changes to xdiff in git could have been committed to the git 
> repository only.

Yes, but if it would have been integrated as a submodule it obviously
would have been committed to the xdiff submodule inside the git
repository.
So the changes are really part of the git repository, but you could go
to the "git/xdiff" directory and only see the changes in the submodule,
without the normal supermodule history.

> Independently, they could have been published to upstream and be put
> into the xdiff repository by its author.  But the last part is what
> only the owner of the xdiff repository is able to decide.

Of course, everything still works like normal git repositories.

> >You can't change the submodule contents in the supermodule without also
> >changing the submodule.
> >This is just like you can't commit a change to a file without also
> >changing the file.
> 
> There is a difference. I would say: If you commit a change to a file in 
> one branch, it need not be changed in all branches.

But you need to change _at_least_ one branch.
Otherwise you cannot commit to a branch.

So if you change something in a submodule, you have to change one branch
in the submodule.
If you call git-checkout in the supermodule this will result in
something like a git-reset in the submodule.

> >No, this is the benefit you get by introducing submodules.
> >Why would you want to introduce a submodule when it is not linked to the
> >supermodule?
> 
> Because the submodule must be independent of the supermodule.
> 
> I see where you are coming from. You have one project that is divided 
> into subprojects but the subprojects themselves are not independent.
> 
> What I would like to solve is the followng: You have a project X, an 
> this project is made part of two other projects Y and Z (as a submodule 
> or subproject or whatever you want to call it). The project X need not, 
> must not or cannot care that it was made a subproject. But in projects Y 
> and Z, you must be able to bugfix or extend or modify the code of 
> projectX, and you must be able to push and pull changes between all 
> three projects (of course we are only talking about the code part of 
> project X).

Of course.

So if you wanted to check out everything, you could have something like
~/src/X, ~/src/Y/X, and ~/src/Z/X.
All of these would be GIT repositories, all of them have their
independent branches.

What I am saying is just that if you update Y, and the new Y contains an
updated version of X, then ~/src/Y/X/.git/refs/heads/master will be
changed by the pull, resulting in the new version of X being checked out
in ~/src/Y/X (alongside all the other updates inside ~/src/Y).
This of course is independend from ~/src/X or  ~/src/Z/X.

> Do you see where your solution makes that impossible, and that with more 
> changes to the repository layout?

No ;-)

-- 
Martin Waitz

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [RFC] Submodules in GIT
From: Linus Torvalds @ 2006-12-01 16:49 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: Martin Waitz, sf, git
In-Reply-To: <45705A94.2070509@op5.se>



On Fri, 1 Dec 2006, Andreas Ericsson wrote:

> Martin Waitz wrote:
> > 
> > But if the supermodule contains changes to the submodule, you still
> > have to change the submodule.  And this implies changing the submodule
> > HEAD or some branch.
> > 
> 
> Not really. I fail to see why HEAD needs to be changed so long as the commit
> is in the submodule's odb.

Right. A commit in the supermodule should _not_ imply a commit in the 
submodule.

Maybe I should take a look at the code, but it sounds like people are 
still trying to "mix" submodules too much. 

Think of it this way: one common use for submodules is really to just 
(occasionally) track somebody elses code. The submodule should be a 
totally pristine copy from somebody else (ie it might be the "intel driver 
for X.org" submodule, maintained within intel), and the supermodule just 
refers to it indirectly (ie the supermodule might be the "Fedora Core X 
group" which contains all the different drivers from different people).

So anything that mixes super-modules and sub-modules too much will always 
break this kind of model.

A supermodule can never "contain changes" to a submodule. A supermodule 
would always just point to the submodule, and not have any changes 
what-so-ever of its own. The submodule is self-sufficient, and always 
contains all its _own_ changes.


^ permalink raw reply

* Re: selective git-update-index per diff(1) chunks
From: Anand Kumria @ 2006-12-01 16:45 UTC (permalink / raw)
  To: git
In-Reply-To: <7v3b7zalsq.fsf@assigned-by-dhcp.cox.net>

On Fri, 01 Dec 2006 03:38:13 -0800, Junio C Hamano wrote:

> Peter Baumann <Peter.B.Baumann@stud.informatik.uni-erlangen.de>
> writes:
> 
>> I don't think it belongs in the plumbing, the git-update-index but I
>> think something like this would be very usefull.
>>
>> AFAIR darcs has this functionality. It selectively ask for each hunk if
>> it should be commited. This would be awfull to have in git.
> 
> I concur, on both counts.  My own now-defunct Porcelain had the
> darcs style interactive hunk selection because it felt so
> useful (and sometimes it was).

Is there a good receipe on how to do this? Everytime I do it, I try a
different method; since I'm testing out my understanding of things.

It'd nice to have some of these "advanced receipes" that people often do
noted down somewhere.

Sometimes I feel git is kind of like the Emacs of VCS ... there is always
more to learn, even when you think you have a good handle on things.

Cheers,
Anand

^ permalink raw reply

* Re: [RFC] Submodules in GIT
From: Andreas Ericsson @ 2006-12-01 16:38 UTC (permalink / raw)
  To: Martin Waitz; +Cc: sf, git
In-Reply-To: <20061201150045.GZ18810@admingilde.org>

Martin Waitz wrote:
> hoi :)
> 
> On Fri, Dec 01, 2006 at 03:52:29PM +0100, Andreas Ericsson wrote:
>>> Remember: if you git-pull in the supermodule, you want to update the
>>> whole thing, including all submodules.
>>>
>> Only if the new commits I pull into the supermodule DAG has commits 
>> which includes a new shapshot of the submodule, otherwise it wouldn't be 
>> necessary.
> 
> Of course.
> 
> But if the supermodule contains changes to the submodule, you still
> have to change the submodule.  And this implies changing the submodule
> HEAD or some branch.
> 

Not really. I fail to see why HEAD needs to be changed so long as the 
commit is in the submodule's odb.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se

^ permalink raw reply

* Re: [RFC] Submodules in GIT
From: Martin Waitz @ 2006-12-01 16:15 UTC (permalink / raw)
  To: Stephan Feder; +Cc: git
In-Reply-To: <45705283.5080900@b-i-t.de>

[-- Attachment #1: Type: text/plain, Size: 643 bytes --]

hoi :)

On Fri, Dec 01, 2006 at 05:04:19PM +0100, Stephan Feder wrote:
> I was looking into git-init-module.sh (branch module2). There you set up 
> a separate git repository for the submodule and store references to it 
> into the supermodules's repository.

yes.

This is to be able to call git-fsck-objects and git-prune in the
toplevel supermodule.  When traversing the object tree, it already knows
about all submodule, but only about those versions that are really part
of their supermodule.
So I have to teach git about separate submodule branches which may be
used, in order not to prune them away.

-- 
Martin Waitz

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox