Git development
 help / color / mirror / Atom feed
* Re: git 1.2 works on Solaris, AIX
From: Junio C Hamano @ 2006-02-14  6:13 UTC (permalink / raw)
  To: Jason Riedy; +Cc: git
In-Reply-To: <12579.1139893961@lotus.CS.Berkeley.EDU>

Thanks.  So let's leave the 1.2.X maintenance series as is at
least for now.

^ permalink raw reply

* Re: [ANNOUNCE] pg - A patch porcelain for GIT
From: Shawn Pearce @ 2006-02-14  6:14 UTC (permalink / raw)
  To: git; +Cc: Catalin Marinas
In-Reply-To: <20060214045618.GA12844@spearce.org>

Shawn Pearce <spearce@spearce.org> wrote:
> > >     pg operations generally perform faster than StGIT operations,
> > >     at least on my large (~7000 file) repositories.
> > 
> > Might be possible but I haven't done any tests. There are some
> > optimisations in StGIT that make it pretty fast: (1) if the base of
> > the patch has not changed, it can fast-forward the pushed patches
> > which is O(1) and (2) StGIT first tries to use git-apply when pushing
> > a patch and use a three-way merge only if this fails (the operation
> > usually succeeds for most of the patches). There are some speed
> > problems with three-way merging if there are many file
> > removals/additions because the external merge tool is called for each
> > of them but the same problem exists for any other tool.

I did a quick benchmark of the latest StGIT and pg versions available
by cloning a linux repository twice (pg and stg) and constructing
an identical patch in in each which modified the same set of files
(3 files in 3 different subdirectories).

Popping and pushing this patch of 3 files is a fast forward/rewind
case to both implementations, but pg was faster for me:

stg pop; stg push (fast-forward)
  pop  real 0m13.824s user 0m1.904s sys 0m3.934s
  pop  real 0m13.670s user 0m1.882s sys 0m3.973s
  pop  real 0m21.070s user 0m2.005s sys 0m4.069s
  pop  real 0m15.346s user 0m1.757s sys 0m3.846s
  pop  real 0m16.960s user 0m1.888s sys 0m3.866s
          
  push real 0m20.650s user 0m2.027s sys 0m4.015s
  push real 0m15.624s user 0m1.958s sys 0m3.966s
  push real 0m13.277s user 0m1.746s sys 0m3.796s
  push real 0m12.739s user 0m1.764s sys 0m3.822s
  push real 0m15.161s user 0m1.973s sys 0m3.939s
        
pg-pop; pg-push (fast-forward)
  pop  real 0m10.009s user 0m1.919s sys 0m2.265s
  pop  real 0m 4.710s user 0m1.692s sys 0m1.560s
  pop  real 0m 4.333s user 0m1.664s sys 0m1.554s
  pop  real 0m 5.480s user 0m1.848s sys 0m1.638s
  pop  real 0m 4.412s user 0m1.680s sys 0m1.604s
          
  push real 0m5.813s user 0m1.750s sys 0m1.733s
  push real 0m4.345s user 0m1.686s sys 0m1.632s
  push real 0m5.326s user 0m1.721s sys 0m1.658s
  push real 0m4.740s user 0m1.691s sys 0m1.647s
  push real 0m4.487s user 0m1.702s sys 0m1.637s


I tried to do the merge case which requires reconstructing the
patch onto a new base revision.  This was easy to test over and over
again on pg (pg-rebase; pg-rebase --undo) but I don't know how I can
safely undo the stg pull so I can repeat it on the stg repository.
Instead I tested git-diff-tree|git-apply as that's what StGIT uses
internally.  StGIT does a check for a clean tree before starting
its merge so I cheated here and used the pg version of that check
as part of the diff/apply cost to try and make it slightly more
fair to pg-rebase.

git-diff-tree -p %s %s | git-apply --index
  diff/apply real 0m6.246s user 0m1.377s sys 0m1.634s
  diff/apply real 0m5.293s user 0m1.342s sys 0m1.591s
  diff/apply real 0m5.929s user 0m1.445s sys 0m1.614s
  diff/apply real 0m5.258s user 0m1.333s sys 0m1.567s
  diff/apply real 0m5.255s user 0m1.339s sys 0m1.581s

pg-rebase; pg-rebase --undo (merge)
  rebase real 0m9.505s user 0m4.028s sys 0m3.366s
  rebase real 0m9.415s user 0m4.020s sys 0m3.334s
  rebase real 0m9.387s user 0m4.028s sys 0m3.364s
  rebase real 0m9.159s user 0m4.024s sys 0m3.353s
  rebase real 0m9.008s user 0m4.025s sys 0m3.326s

  undo   real 0m6.531s user 0m1.852s sys 0m2.403s
  undo   real 0m6.383s user 0m1.815s sys 0m2.405s
  undo   real 0m6.510s user 0m1.849s sys 0m2.406s
  undo   real 0m6.519s user 0m1.846s sys 0m2.408s
  undo   real 0m6.496s user 0m1.878s sys 0m2.413s

I guess you could say I didn't entirely expect this result.
The diff-tree/apply approach is faster for a single commit then
read-tree -u -m is; even if totally different files are being
impacted and thus all stages collapse neatly to stage 0 in the index.
No wonder StGIT uses diff/apply!

-- 
Shawn.

^ permalink raw reply

* Re: older git archive access broken in 1.2.0?
From: Greg KH @ 2006-02-14  6:15 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, tglx
In-Reply-To: <7vek26wkwu.fsf@assigned-by-dhcp.cox.net>

On Mon, Feb 13, 2006 at 09:48:17PM -0800, Junio C Hamano wrote:
> Greg KH <greg@kroah.com> writes:
> 
> > I was trying to find where something changed in the historical Linux
> > kernel git tree:
> > 	rsync://rsync.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/
> >
> > when I noticed that the latest version of git doesn't seem to like this
> > archive.  I can't clone it, but 'git log' and 'git whatchanged' seems to
> > work fine.
> 
> I think 1.2.0 may be a coincidence.  history.git/ mistakenly has
> an extra .git subdirectory underneath it.  Removing it should
> make things to work again I suspect.

Ah, doh, that was simple.  Thanks for the quick response.

greg k-h

^ permalink raw reply

* Re: diffstat wierdness with 'git format-patch' output
From: Greg KH @ 2006-02-14  6:34 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vveviv5d1.fsf@assigned-by-dhcp.cox.net>

On Mon, Feb 13, 2006 at 10:09:30PM -0800, Junio C Hamano wrote:
> Greg KH <greg@kroah.com> writes:
> 
> > Hm, in looking at it closer, it's probably the last two lines of the
> > file, the signature that git format-patch adds to the message:
> > 	-- 
> > 	1.2.0
> 
> If that is the case, it's unfortunate that diffstat is broken
> and is not properly counting lines to tell which lines are part
> of the patch and which lines are not.
> 
> Have you tried "git apply --stat" instead?

How would that work after I've allready applied the patches to a branch?

> > Any way to suppress these?
> 
> Sorry, there is no option to disable that, but the stuff is
> GPLv2 so you can do whatever ;-).

Bah, make me go create a patch :)

> The string "-- \n" is an established convention to mark the
> beginning of the signature (or whatever inmaterial stuff that
> follow the message contents), so changing the marker is
> pointless -- if we want the option it should be to delete those
> two lines altogether.

Oh I understand what it is and it does follow the proper convention.
Maybe we just need an extra line of padding in there before the
signature or something... I'll go play with it.

> I personally find it useful to see the trend of version of tools
> people use on the public mailing list, and that was the primary
> reason it is there.

Why not just add a "X-Git-Version: 1.2.0" flag to the message instead?

thanks,

greg k-h

^ permalink raw reply

* Re: diffstat wierdness with 'git format-patch' output
From: Junio C Hamano @ 2006-02-14  6:37 UTC (permalink / raw)
  To: Greg KH; +Cc: git
In-Reply-To: <20060214063420.GA11851@kroah.com>

Greg KH <greg@kroah.com> writes:

>> Have you tried "git apply --stat" instead?
>
> How would that work after I've allready applied the patches to a branch?

Sorry I was unclear.  By "instead", I meant "instead of running
diffstat -p1".

^ permalink raw reply

* Re: diffstat wierdness with 'git format-patch' output
From: Greg KH @ 2006-02-14  6:42 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <20060214063420.GA11851@kroah.com>

On Mon, Feb 13, 2006 at 10:34:20PM -0800, Greg KH wrote:
> > I personally find it useful to see the trend of version of tools
> > people use on the public mailing list, and that was the primary
> > reason it is there.
> 
> Why not just add a "X-Git-Version: 1.2.0" flag to the message instead?

And here's a patch that does just that.

-----------------

Subject: change git-format-patch to put the git version in the mail header

This is more like other tools that create mail messages, and fixes an
issue of the diffstat program thinking that an extra line was removed
from the patch.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

diff --git a/git-format-patch.sh b/git-format-patch.sh
index e54c9e4..5f6a921 100755
--- a/git-format-patch.sh
+++ b/git-format-patch.sh
@@ -216,6 +216,7 @@ while (<FH>) {
 
 	    print "From: $author_ident\n";
 	    print "Date: $author_date\n";
+	    print "X-Git-Version: @@GIT_VERSION@@\n";
 	}
 	next;
     }
@@ -250,8 +251,6 @@ close FH or die "close $commsg pipe";
 	git-diff-tree -p $diff_opts "$commit" | git-apply --stat --summary
 	echo
 	git-diff-tree -p $diff_opts "$commit"
-	echo "-- "
-	echo "@@GIT_VERSION@@"
 
 	echo
 }

^ permalink raw reply related

* Re: diffstat wierdness with 'git format-patch' output
From: Greg KH @ 2006-02-14  6:44 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vlkwev41k.fsf@assigned-by-dhcp.cox.net>

On Mon, Feb 13, 2006 at 10:37:59PM -0800, Junio C Hamano wrote:
> Greg KH <greg@kroah.com> writes:
> 
> >> Have you tried "git apply --stat" instead?
> >
> > How would that work after I've allready applied the patches to a branch?
> 
> Sorry I was unclear.  By "instead", I meant "instead of running
> diffstat -p1".

That doesn't give me a summary of all of the changes I made to the tree:

$ git apply --stat *.txt
 drivers/hwmon/vt8231.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)
 drivers/hwmon/w83781d.c |   43 +++++++++++++++++++++++++------------------
 1 files changed, 25 insertions(+), 18 deletions(-)
 Documentation/hwmon/w83627hf |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
 drivers/hwmon/it87.c         |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
 drivers/i2c/busses/i2c-isa.c |   12 ------------
 1 files changed, 0 insertions(+), 12 deletions(-)


Instead of:

 Documentation/hwmon/w83627hf |    4 ++++
 drivers/hwmon/it87.c         |    3 ++-
 drivers/hwmon/vt8231.c       |    8 ++++----
 drivers/hwmon/w83781d.c      |   43 +++++++++++++++++++++++++------------------
 drivers/i2c/busses/i2c-isa.c |   12 ------------
 5 files changed, 35 insertions(+), 35 deletions(-)

Which is what I need to put into a "please pull from this tree" email
message.

thanks,

greg k-h

^ permalink raw reply

* Re: diffstat wierdness with 'git format-patch' output
From: Greg KH @ 2006-02-14  6:52 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <20060214064256.GA19667@kroah.com>

On Mon, Feb 13, 2006 at 10:42:56PM -0800, Greg KH wrote:
> On Mon, Feb 13, 2006 at 10:34:20PM -0800, Greg KH wrote:
> > > I personally find it useful to see the trend of version of tools
> > > people use on the public mailing list, and that was the primary
> > > reason it is there.
> > 
> > Why not just add a "X-Git-Version: 1.2.0" flag to the message instead?
> 
> And here's a patch that does just that.
> 
> -----------------
> 
> Subject: change git-format-patch to put the git version in the mail header
> 
> This is more like other tools that create mail messages, and fixes an
> issue of the diffstat program thinking that an extra line was removed
> from the patch.
> 
> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
> 
> diff --git a/git-format-patch.sh b/git-format-patch.sh
> index e54c9e4..5f6a921 100755
> --- a/git-format-patch.sh
> +++ b/git-format-patch.sh
> @@ -216,6 +216,7 @@ while (<FH>) {
>  
>  	    print "From: $author_ident\n";
>  	    print "Date: $author_date\n";
> +	    print "X-Git-Version: @@GIT_VERSION@@\n";

Hm, git-send-email doesn't see this, so it doesn't get sent out if you
use that tool.

I can fix that to just put the version number in the message too, like
it adds the "X-Mailer" field, if people think this is really worth it...

thanks,

greg k-h

^ permalink raw reply

* Re: older git archive access broken in 1.2.0?
From: Thomas Gleixner @ 2006-02-14  7:00 UTC (permalink / raw)
  To: Greg KH; +Cc: Junio C Hamano, git, tglx
In-Reply-To: <20060214061529.GA853@kroah.com>

On Mon, 2006-02-13 at 22:15 -0800, Greg KH wrote:
> > I think 1.2.0 may be a coincidence.  history.git/ mistakenly has
> > an extra .git subdirectory underneath it.  Removing it should
> > make things to work again I suspect.
> 
> Ah, doh, that was simple.  Thanks for the quick response.

Fixed. No idea how it got there. 

	tglx

^ permalink raw reply

* Re: diffstat wierdness with 'git format-patch' output
From: Junio C Hamano @ 2006-02-14  7:10 UTC (permalink / raw)
  To: Greg KH; +Cc: git
In-Reply-To: <20060214065224.GA20541@kroah.com>

Greg KH <greg@kroah.com> writes:

> Hm, git-send-email doesn't see this, so it doesn't get sent out if you
> use that tool.

And people are very likely to remove it by hand.

Another possibility would be to use "git apply --numstat" and
add numbers up in your script, but that would not give you a
nice graph output either X-<.

I'd say if you really care we should just remove those two
lines, and remember I am _very_ receptive from such suggestion
from prominent kernel people.

^ permalink raw reply

* Re: Quick question
From: Junio C Hamano @ 2006-02-14  7:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git, Radoslaw Szkodzinski
In-Reply-To: <Pine.LNX.4.64.0602130848220.3691@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> Which is admittedly insane. You don't want to exclude directories. Or 
> maybe you do, but then we should add the "/" to the end before we do the 
> exclusion.
>
> This patch (untested) will never exclude directories. Which may or may not 
> be the right thing. 
>
> Junio? Others? Comments?
>
> 		Linus

I might have sounded negative or happy with status quo in my
earlier messages but that was not intended.  I am swamped and
have not formed an opinion.

^ permalink raw reply

* [PATCH] combine-diff: diff-files fix.
From: Junio C Hamano @ 2006-02-14  7:53 UTC (permalink / raw)
  To: git

When showing a conflicted merge from index stages and working
tree file, we did not fetch the mode from the working tree,
and mistook that as a deleted file.  Also if the manual
resolution (or automated resolution by git rerere) ended up
taking either parent's version, we did not show _anything_ for
that path.  Either was quite bad and confusing.

Signed-off-by: Junio C Hamano <junkio@cox.net>

---
 * This will be part of 1.2.1 maintenance series.

 combine-diff.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

713a11fceb662f275b5e1294acc6f38674834941
diff --git a/combine-diff.c b/combine-diff.c
index a38f01b..d812600 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -630,9 +630,10 @@ static int show_patch_diff(struct combin
 	int i, show_hunks, shown_header = 0;
 	char ourtmp_buf[TMPPATHLEN];
 	char *ourtmp = ourtmp_buf;
+	int working_tree_file = !memcmp(elem->sha1, null_sha1, 20);
 
 	/* Read the result of merge first */
-	if (memcmp(elem->sha1, null_sha1, 20)) {
+	if (!working_tree_file) {
 		result = grab_blob(elem->sha1, &size);
 		write_to_temp_file(ourtmp, result, size);
 	}
@@ -646,6 +647,7 @@ static int show_patch_diff(struct combin
 			int len = st.st_size;
 			int cnt = 0;
 
+			elem->mode = DIFF_FILE_CANON_MODE(st.st_mode);
 			size = len;
 			result = xmalloc(len + 1);
 			while (cnt < len) {
@@ -661,6 +663,7 @@ static int show_patch_diff(struct combin
 		else {
 			/* deleted file */
 			size = 0;
+			elem->mode = 0;
 			result = xmalloc(1);
 			result[0] = 0;
 			ourtmp = "/dev/null";
@@ -716,7 +719,7 @@ static int show_patch_diff(struct combin
 
 	show_hunks = make_hunks(sline, cnt, num_parent, dense);
 
-	if (show_hunks || mode_differs) {
+	if (show_hunks || mode_differs || working_tree_file) {
 		const char *abb;
 
 		if (header) {
@@ -731,8 +734,6 @@ static int show_patch_diff(struct combin
 		putchar('\n');
 		printf("index ");
 		for (i = 0; i < num_parent; i++) {
-			if (elem->parent[i].mode != elem->mode)
-				mode_differs = 1;
 			abb = find_unique_abbrev(elem->parent[i].sha1,
 						 DEFAULT_ABBREV);
 			printf("%s%s", i ? "," : "", abb);
-- 
1.2.0.g45dc

^ permalink raw reply related

* [PATCH] git-commit: Now --only semantics is the default.
From: Junio C Hamano @ 2006-02-14  7:53 UTC (permalink / raw)
  To: git

This changes the "git commit paths..." to default to --only
semantics from traditional --include semantics, as agreed on the
list.

Signed-off-by: Junio C Hamano <junkio@cox.net>

---

 * This will be part of the post 1.2.0 "master" updates, towards
   1.3.0 development track.

 Documentation/git-commit.txt |   17 +++++++++++------
 git-commit.sh                |    9 +++------
 2 files changed, 14 insertions(+), 12 deletions(-)

4170a19587280eeb3663a47a6fd993910de78076
diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index 53b64fa..214ed23 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -8,8 +8,8 @@ git-commit - Record your changes
 SYNOPSIS
 --------
 [verse]
-'git-commit' [-a] [-i] [-s] [-v] [(-c | -C) <commit> | -F <file> | -m <msg>]
-	   [-e] [--author <author>] [--] <file>...
+'git-commit' [-a] [-s] [-v] [(-c | -C) <commit> | -F <file> | -m <msg>]
+	   [-e] [--author <author>] [--] [[-i | -o ]<file>...]
 
 DESCRIPTION
 -----------
@@ -73,15 +73,20 @@ OPTIONS
 	commit the whole index.  This is the traditional
 	behaviour.
 
---::
-	Do not interpret any more arguments as options.
-
-<file>...::
+-o|--only::
 	Commit only the files specified on the command line.
 	This format cannot be used during a merge, nor when the
 	index and the latest commit does not match on the
 	specified paths to avoid confusion.
 
+--::
+	Do not interpret any more arguments as options.
+
+<file>...::
+	Files to be committed.  The meaning of these is
+	different between `--include` and `--only`.  Without
+	either, it defaults `--only` semantics.
+
 If you make a commit and then found a mistake immediately after
 that, you can recover from it with gitlink:git-reset[1].
 
diff --git a/git-commit.sh b/git-commit.sh
index 59551d9..ab5e6bc 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -3,7 +3,7 @@
 # Copyright (c) 2005 Linus Torvalds
 # Copyright (c) 2006 Junio C Hamano
 
-USAGE='[-a] [-i] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit>] [-e] [--author <author>] [<path>...]'
+USAGE='[-a] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit>] [-e] [--author <author>] [[-i | -o] <path>...]'
 SUBDIRECTORY_OK=Yes
 . git-sh-setup
 
@@ -340,11 +340,8 @@ case "$#,$also$only" in
 0,)
   ;;
 *,)
-  echo >&2 "assuming --include paths..."
-  also=t
-  # Later when switch the defaults, we will replace them with these:
-  # echo >&2 "assuming --only paths..."
-  # also=
+  echo >&2 "assuming --only paths..."
+  also=
 
   # If we are going to launch an editor, the message won't be
   # shown without this...
-- 
1.2.0.g45dc

^ permalink raw reply related

* [PATCH] Documentation: git-commit in 1.2.X series defaults to --include.
From: Junio C Hamano @ 2006-02-14  7:53 UTC (permalink / raw)
  To: git

The documentation was mistakenly describing the --only semantics to
be default.  The 1.2.0 release and its maintenance series 1.2.X will
keep the traditional --include semantics as the default.  Clarify the
situation.

Signed-off-by: Junio C Hamano <junkio@cox.net>

---

 * This will be part of 1.2.1 maintenance series.

 Documentation/git-commit.txt |   34 +++++++++++++++++++++++++++-------
 1 files changed, 27 insertions(+), 7 deletions(-)

64491e1ea95acde1aa77db539ba498593a0fcbc5
diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index 53b64fa..5b1b4d3 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -8,8 +8,8 @@ git-commit - Record your changes
 SYNOPSIS
 --------
 [verse]
-'git-commit' [-a] [-i] [-s] [-v] [(-c | -C) <commit> | -F <file> | -m <msg>]
-	   [-e] [--author <author>] [--] <file>...
+'git-commit' [-a] [-s] [-v] [(-c | -C) <commit> | -F <file> | -m <msg>]
+	   [-e] [--author <author>] [--] [[-i | -o ]<file>...]
 
 DESCRIPTION
 -----------
@@ -73,19 +73,39 @@ OPTIONS
 	commit the whole index.  This is the traditional
 	behaviour.
 
---::
-	Do not interpret any more arguments as options.
-
-<file>...::
+-o|--only::
 	Commit only the files specified on the command line.
 	This format cannot be used during a merge, nor when the
 	index and the latest commit does not match on the
 	specified paths to avoid confusion.
 
+--::
+	Do not interpret any more arguments as options.
+
+<file>...::
+	Files to be committed.  The meaning of these is
+	different between `--include` and `--only`.  Without
+	either, it defaults `--include` semantics.
+
 If you make a commit and then found a mistake immediately after
 that, you can recover from it with gitlink:git-reset[1].
 
 
+WARNING
+-------
+
+The 1.2.0 and its maintenance series 1.2.X will keep the
+traditional `--include` semantics as the default when neither
+`--only` nor `--include` is specified and `paths...` are given.
+This *will* change during the development towards 1.3.0 in the
+'master' branch of `git.git` repository.  If you are using this
+command in your scripts, and you depend on the traditional
+`--include` semantics, please update them to explicitly ask for
+`--include` semantics.  Also if you are used to making partial
+commit using `--include` semantics, please train your fingers to
+say `git commit --include paths...` (or `git commit -i paths...`).
+
+
 Discussion
 ----------
 
@@ -101,7 +121,7 @@ even the command is invoked from a subdi
 That is, update the specified paths to the index and then commit
 the whole tree.
 
-`git commit paths...` largely bypasses the index file and
+`git commit --only paths...` largely bypasses the index file and
 commits only the changes made to the specified paths.  It has
 however several safety valves to prevent confusion.
 
-- 
1.2.0.g45dc

^ permalink raw reply related

* [PATCH] rebase: allow a hook to refuse rebasing.
From: Junio C Hamano @ 2006-02-14  7:53 UTC (permalink / raw)
  To: git

This lets a hook to interfere a rebase and help prevent certain
branches from being rebased by mistake.  A sample hook to show
how to prevent a topic branch that has already been merged into
publish branch.

Signed-off-by: Junio C Hamano <junkio@cox.net>

---

 * This was done while switching my workflow to more stable
   "next".  A companion script which is more private nature is
   in the TODO branch, file TO.  I use that one to manage the
   "next" branch, and this sample hook prevents me from rebasing
   topic branches too eagerly by mistake.

 git-rebase.sh               |    9 +++
 templates/hooks--pre-rebase |  150 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 159 insertions(+), 0 deletions(-)
 create mode 100644 templates/hooks--pre-rebase

9a111c91b01455ee1ea9f33c60da7ad50d460a7b
diff --git a/git-rebase.sh b/git-rebase.sh
index 16d4359..f84160d 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -36,6 +36,15 @@ other=$(git-rev-parse --verify "$1^0") |
 # Make sure the branch to rebase is valid.
 head=$(git-rev-parse --verify "${2-HEAD}^0") || exit
 
+# If a hook exists, give it a chance to interrupt
+if test -x "$GIT_DIR/hooks/pre-rebase"
+then
+	"$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
+		echo >&2 "The pre-rebase hook refused to rebase."
+		exit 1
+	}
+fi
+
 # If the branch to rebase is given, first switch to it.
 case "$#" in
 2)
diff --git a/templates/hooks--pre-rebase b/templates/hooks--pre-rebase
new file mode 100644
index 0000000..981c454
--- /dev/null
+++ b/templates/hooks--pre-rebase
@@ -0,0 +1,150 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Junio C Hamano
+#
+
+publish=next
+basebranch="$1"
+if test "$#" = 2
+then
+	topic="refs/heads/$2"
+else
+	topic=`git symbolic-ref HEAD`
+fi
+
+case "$basebranch,$topic" in
+master,refs/heads/??/*)
+	;;
+*)
+	exit 0 ;# we do not interrupt others.
+	;;
+esac
+
+# Now we are dealing with a topic branch being rebased
+# on top of master.  Is it OK to rebase it?
+
+# Is topic fully merged to master?
+not_in_master=`git-rev-list --pretty=oneline ^master "$topic"`
+if test -z "$not_in_master"
+then
+	echo >&2 "$topic is fully merged to master; better remove it."
+	exit 1 ;# we could allow it, but there is no point.
+fi
+
+# Is topic ever merged to next?  If so you should not be rebasing it.
+only_next_1=`git-rev-list ^master "^$topic" ${publish} | sort`
+only_next_2=`git-rev-list ^master           ${publish} | sort`
+if test "$only_next_1" = "$only_next_2"
+then
+	not_in_topic=`git-rev-list "^$topic" master`
+	if test -z "$not_in_topic"
+	then
+		echo >&2 "$topic is already up-to-date with master"
+		exit 1 ;# we could allow it, but there is no point.
+	else
+		exit 0
+	fi
+else
+	not_in_next=`git-rev-list --pretty=oneline ^${publish} "$topic"`
+	perl -e '
+		my $topic = $ARGV[0];
+		my $msg = "* $topic has commits already merged to public branch:\n";
+		my (%not_in_next) = map {
+			/^([0-9a-f]+) /;
+			($1 => 1);
+		} split(/\n/, $ARGV[1]);
+		for my $elem (map {
+				/^([0-9a-f]+) (.*)$/;
+				[$1 => $2];
+			} split(/\n/, $ARGV[2])) {
+			if (!exists $not_in_next{$elem->[0]}) {
+				if ($msg) {
+					print STDERR $msg;
+					undef $msg;
+				}
+				print STDERR " $elem->[1]\n";
+			}
+		}
+	' "$topic" "$not_in_next" "$not_in_master"
+	exit 1
+fi
+
+exit 0
+
+################################################################
+
+This sample hook safeguards topic branches that have been
+published from being rewound.
+
+The workflow assumed here is:
+
+ * Once a topic branch forks from "master", "master" is never
+   merged into it again (either directly or indirectly).
+
+ * Once a topic branch is fully cooked and merged into "master",
+   it is deleted.  If you need to build on top of it to correct
+   earlier mistakes, a new topic branch is created by forking at
+   the tip of the "master".  This is not strictly necessary, but
+   it makes it easier to keep your history simple.
+
+ * Whenever you need to test or publish your changes to topic
+   branches, merge them into "next" branch.
+
+The script, being an example, hardcodes the publish branch name
+to be "next", but it is trivial to make it configurable via
+$GIT_DIR/config mechanism.
+
+With this workflow, you would want to know:
+
+(1) ... if a topic branch has ever been merged to "next".  Young
+    topic branches can have stupid mistakes you would rather
+    clean up before publishing, and things that have not been
+    merged into other branches can be easily rebased without
+    affecting other people.  But once it is published, you would
+    not want to rewind it.
+
+(2) ... if a topic branch has been fully merged to "master".
+    Then you can delete it.  More importantly, you should not
+    build on top of it -- other people may already want to
+    change things related to the topic as patches against your
+    "master", so if you need further changes, it is better to
+    fork the topic (perhaps with the same name) afresh from the
+    tip of "master".
+
+Let's look at this example:
+
+		   o---o---o---o---o---o---o---o---o---o "next"
+		  /       /           /           /
+		 /   a---a---b A     /           /
+		/   /               /           /
+	       /   /   c---c---c---c B         /
+	      /   /   /             \         /
+	     /   /   /   b---b C     \       /
+	    /   /   /   /             \     /
+    ---o---o---o---o---o---o---o---o---o---o---o "master"
+
+
+A, B and C are topic branches.
+
+ * A has one fix since it was merged up to "next".
+
+ * B has finished.  It has been fully merged up to "master" and "next",
+   and is ready to be deleted.
+
+ * C has not merged to "next" at all.
+
+We would want to allow C to be rebased, refuse A, and encourage
+B to be deleted.
+
+To compute (1):
+
+	git-rev-list ^master ^topic next
+	git-rev-list ^master        next
+
+	if these match, topic has not merged in next at all.
+
+To compute (2):
+
+	git-rev-list master..topic
+
+	if this is empty, it is fully merged to "master".
-- 
1.2.0.g45dc

^ permalink raw reply related

* Re: [ANNOUNCE] pg - A patch porcelain for GIT
From: Catalin Marinas @ 2006-02-14  9:26 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git
In-Reply-To: <20060213210001.GA31278@pasky.or.cz>

Petr Baudis <pasky@suse.cz> wrote:
>   Some common gripes for both StGIT and pg (well, I'm using some
> ridiculously old StGIT version, so this may not apply anymore there):
>
> 	* stg new --force - seriously, what's the point?! I always to
> 	the change first and when it's any good, I want to create a
> 	patch for it.

This was fixed couple of weeks ago in the main branch. No need to pass
--force anymore.

> 	* I can't just get the patch in its "canonical ready-to-mail
> 	form" on stdout so that I could easily review it. Why is
> 	pg-export insisting to dump it to a file?

To view the patch you can use 'stg diff -r <patch>/' but it doesn't
show the description. Dumping the full patch on stdout would be
useful, indeed. The export and mail commands use different templates
and the latter even adds the standard mail headers. Which of these two
commands would you prefer to dump the patch on stdout (both is fine as
well)?

Another thing that's missing in StGIT is the import of a series of
patches. At the moment I run a small shell script to import individual
patches.

-- 
Catalin

^ permalink raw reply

* Re: [ANNOUNCE] pg - A patch porcelain for GIT
From: Karl Hasselström @ 2006-02-14 10:08 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git
In-Reply-To: <tnxoe1aqoj2.fsf@arm.com>

On 2006-02-14 09:26:41 +0000, Catalin Marinas wrote:

> Another thing that's missing in StGIT is the import of a series of
> patches. At the moment I run a small shell script to import
> individual patches.

One thing I would like to see in stgit is the opposite of "stg
commit"; instead of converting patches to regular commits, take the
topmost regular commits and convert them to patches.

For example, "stg uncommit foo bar baz" would -- regardless of any
existing patches, applied or not -- convert the top three regular
commits, with comments and all, to stgit patches called foo, bar, and
baz. These would be already applied, at the bottom of the stack. I
imagine all one would have to do is to modify some stgit metadata, so
the operation could be really cheap.

Of course, "stg uncommit" is allowed to reject any commit with more
than one parent, since those can't be represented as stgit patches.

This would perhaps not add much power to an all-stgit workflow, but it
would be a really convenient way to edit recent git history. Sort of
like a more convenient rebase. And a great way to lure new users. :-)

-- 
Karl Hasselström, kha@treskal.com
      www.treskal.com/kalle

^ permalink raw reply

* Re: [PATCH] Add git-annotate - a tool for annotating files with the revision and person that created each line in the file.
From: Fredrik Kuivinen @ 2006-02-14 10:51 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: Junio C Hamano, Johannes Schindelin, Franck Bui-Huu, git
In-Reply-To: <20060210112541.GA3513@linux-mips.org>

On Fri, Feb 10, 2006 at 11:25:41AM +0000, Ralf Baechle wrote:
> The dependency on Python 2.4 already is a problem for installation on some
> systems ... 

I understand that in the environments where the Python dependency is a
problem it is probably not due to the specific version. However, if
WITH_OWN_SUBPROCESS is defined in the Makefile then Python 2.3 should
work fine too (this is actually automatically detected now, so you
shouldn't have to do anything special to use Python 2.3).

- Fredrik

^ permalink raw reply

* Re: [ANNOUNCE] pg - A patch porcelain for GIT
From: Chuck Lever @ 2006-02-14 15:22 UTC (permalink / raw)
  To: Karl Hasselström; +Cc: Catalin Marinas, git
In-Reply-To: <20060214100844.GA1234@diana.vm.bytemark.co.uk>

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

Karl Hasselström wrote:
> On 2006-02-14 09:26:41 +0000, Catalin Marinas wrote:
> 
> 
>>Another thing that's missing in StGIT is the import of a series of
>>patches. At the moment I run a small shell script to import
>>individual patches.
> 
> 
> One thing I would like to see in stgit is the opposite of "stg
> commit"; instead of converting patches to regular commits, take the
> topmost regular commits and convert them to patches.
> 
> For example, "stg uncommit foo bar baz" would -- regardless of any
> existing patches, applied or not -- convert the top three regular
> commits, with comments and all, to stgit patches called foo, bar, and
> baz. These would be already applied, at the bottom of the stack. I
> imagine all one would have to do is to modify some stgit metadata, so
> the operation could be really cheap.
> 
> Of course, "stg uncommit" is allowed to reject any commit with more
> than one parent, since those can't be represented as stgit patches.
> 
> This would perhaps not add much power to an all-stgit workflow, but it
> would be a really convenient way to edit recent git history. Sort of
> like a more convenient rebase. And a great way to lure new users. :-)

i think you want "stg pick --reverse" ?

[-- Attachment #2: cel.vcf --]
[-- Type: text/x-vcard, Size: 451 bytes --]

begin:vcard
fn:Chuck Lever
n:Lever;Charles
org:Network Appliance, Incorporated;Open Source NFS Client Development
adr:535 West William Street, Suite 3100;;Center for Information Technology Integration;Ann Arbor;MI;48103-4943;USA
email;internet:cel@citi.umich.edu
title:Member of Technical Staff
tel;work:+1 734 763-4415
tel;fax:+1 734 763 4434
tel;home:+1 734 668-1089
x-mozilla-html:FALSE
url:http://troy.citi.umich.edu/u/cel/
version:2.1
end:vcard


^ permalink raw reply

* cg-clean, cg-status improvements
From: Pavel Roskin @ 2006-02-14 15:28 UTC (permalink / raw)
  To: Petr Baudis, git

Hello, Petr!

Is cogito 0.17 going to require git 1.2.0?  If so, I'm ready to submit a
patch for cg-clean that would use the fixed functionality of git
regarding ignores when run in subdirectories (commit
701ca744e386c2429ca44072ea987bbb4bdac7ce).  I think cg-status can be
improved as well.

If cogito 0.17 is not going to require git 1.2.0, I'm ready to add a
temporary workaround for older versions of git.

The problem with cg-clean right now is that it removes contents of
untracked directories by default, which makes it pointless to keep the
directories.  I submitted a patch for that, but it it wasn't noticed.
Anyway, I can do it better now.

-- 
Regards,
Pavel Roskin

^ permalink raw reply

* Re: cg-clean, cg-status improvements
From: Petr Baudis @ 2006-02-14 15:53 UTC (permalink / raw)
  To: Pavel Roskin; +Cc: git
In-Reply-To: <1139930899.1944.13.camel@dv>

  Hello,

Dear diary, on Tue, Feb 14, 2006 at 04:28:19PM CET, I got a letter
where Pavel Roskin <proski@gnu.org> said that...
> Hello, Petr!
> 
> Is cogito 0.17 going to require git 1.2.0?  If so, I'm ready to submit a
> patch for cg-clean that would use the fixed functionality of git
> regarding ignores when run in subdirectories (commit
> 701ca744e386c2429ca44072ea987bbb4bdac7ce).  I think cg-status can be
> improved as well.
> 
> If cogito 0.17 is not going to require git 1.2.0, I'm ready to add a
> temporary workaround for older versions of git.

  I didn't plan to require git 1.2.0 with 0.17, so it would be better if
you could do the workaround. But if the workaround means significant
hassle, it's no biggie if git 1.2.0 will be required.

> The problem with cg-clean right now is that it removes contents of
> untracked directories by default, which makes it pointless to keep the
> directories.  I submitted a patch for that, but it it wasn't noticed.
> Anyway, I can do it better now.

  Hmm, strange, I really did not notice the patch. Well, I'm certainly
interested.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Of the 3 great composers Mozart tells us what it's like to be human,
Beethoven tells us what it's like to be Beethoven and Bach tells us
what it's like to be the universe.  -- Douglas Adams

^ permalink raw reply

* Re: [ANNOUNCE] pg - A patch porcelain for GIT
From: Karl Hasselström @ 2006-02-14 16:07 UTC (permalink / raw)
  To: Chuck Lever; +Cc: Catalin Marinas, git
In-Reply-To: <43F1F5CB.10402@citi.umich.edu>

On 2006-02-14 10:22:51 -0500, Chuck Lever wrote:

> Karl Hasselström wrote:
>
> > One thing I would like to see in stgit is the opposite of "stg
> > commit"; instead of converting patches to regular commits, take
> > the topmost regular commits and convert them to patches.
> >
> > For example, "stg uncommit foo bar baz" would -- regardless of any
> > existing patches, applied or not -- convert the top three regular
> > commits, with comments and all, to stgit patches called foo, bar,
> > and baz. These would be already applied, at the bottom of the
> > stack. I imagine all one would have to do is to modify some stgit
> > metadata, so the operation could be really cheap.
> >
> > Of course, "stg uncommit" is allowed to reject any commit with
> > more than one parent, since those can't be represented as stgit
> > patches.
> >
> > This would perhaps not add much power to an all-stgit workflow,
> > but it would be a really convenient way to edit recent git
> > history. Sort of like a more convenient rebase. And a great way to
> > lure new users. :-)
>
> i think you want "stg pick --reverse" ?

No, I literally want the opposite of "stg commit", so that the
sequence "stg commit; stg uncommit" has zero net effect.

Say we have the following situation (stack growing downward, of
course):

          :
          |
          a
          |
          b
          |
          c <- bases/master
          |
          d <- applied patch "foo"
          |
          e <- applied patch "bar"; HEAD
          |
          f <- unapplied patch "baz"
          |
          :

In this situation, the hypothetical "stg uncommit" command would have
the following effect:

  $ stg uncommit goo baa

          :
          |
          a <- bases/master
          |
          b <- applied patch "baa"
          |
          c <- applied patch "goo"
          |
          d <- applied patch "foo"
          |
          e <- applied patch "bar"; HEAD
          |
          f <- unapplied patch "baz"
          |
          :

Note that HEAD is unchanged; the only thing that has happend is that
stgit has taken over the topmost two commits, and turned them into
patches. No git operations whatsoever have taken place; all stgit had
to do was change the value of bases/master and add bookkeeping
information for the two new patches.

-- 
Karl Hasselström, kha@treskal.com
      www.treskal.com/kalle

^ permalink raw reply

* several quick questions
From: Nicolas Vilz 'niv' @ 2006-02-14 16:28 UTC (permalink / raw)
  To: git

Hello everyone,

i wonder, how i revoke a straight forward merge of two trees... I
actually wanted to be look like somewhere in the git-repository, where
some branches are merged back with the master tree, but i think, that
wasn't "cg-merge -c <tree to merge with the actual one>"...

my result was that my master tree has now the same sha1-sum as my
development-tree and gitk visualisation differs from that what i saw in
the git-repository. (Several Arrows headed into back into one line...)

maybe that was because i didn't do anything in my master tree in the
meantime.

And another thing, is there no posibility to get back to some commits or
tags? I realized you can rebranch tags... what, if i want to switch back
to git version 1.1.6 in the git repository? Or a certain commit?

do you have to make a new private branch out of the tag 1.1.6?

i used svn and there i could go back some revisions. I haven't found
such a feature in git, yet... but i think i am blind all the time.

I like git very much and every new day I like it more.

Sincerly
Nicolas

^ permalink raw reply

* Re: several quick questions
From: Andreas Ericsson @ 2006-02-14 17:03 UTC (permalink / raw)
  To: Nicolas Vilz 'niv'; +Cc: git
In-Reply-To: <43F20532.5000609@iaglans.de>

Nicolas Vilz 'niv' wrote:
> Hello everyone,
> 
> i wonder, how i revoke a straight forward merge of two trees... I
> actually wanted to be look like somewhere in the git-repository, where
> some branches are merged back with the master tree, but i think, that
> wasn't "cg-merge -c <tree to merge with the actual one>"...
> 
> my result was that my master tree has now the same sha1-sum as my
> development-tree and gitk visualisation differs from that what i saw in
> the git-repository. (Several Arrows headed into back into one line...)
> 
> maybe that was because i didn't do anything in my master tree in the
> meantime.
> 

Correct. The "several arrows" thing is when a merge happens (i.e. two 
simultaneous lines of development crash into one another with 
surprisingly pleasant results most of the time). When you do

$ git checkout -b topic-branch
# work, work, work
$ git checkout master
$ git pull . topic-branch

git will recognize the merge-base as being the current HEAD and simply 
sets HEAD to point to that of topic-branch. This is why it's called a 
fast-forward, since no heavy computing needs to be done to combine the 
two development tracks.

> And another thing, is there no posibility to get back to some commits or
> tags? I realized you can rebranch tags... what, if i want to switch back
> to git version 1.1.6 in the git repository? Or a certain commit?
> 

git reset is your friend.

$ git reset --hard v1.1.6
$ git reset --hard ORIG_HEAD

should do something along the lines of what you want.

> do you have to make a new private branch out of the tag 1.1.6?
> 

No, you don't, but you can if you wish. It's nifty if you want to fork 
the development from a particular branch. In your case, if you really, 
really *want* the arrows pointing to one line, you can do

$ git branch topic-branch HEAD^
# work, work, work
$ git checkout master
$ git pull . topic-branch

That would create one pretty arrow. When multiple tracks of development 
(rather than just two) are combined into one it's called an octopus 
merge. Unless you really know what you're doing, you should try to avoid 
those for small projects, and doing it just for the pretty arrows is.... 
well, let's call it "interesting from the behaviour science scholars 
point of view".


> i used svn and there i could go back some revisions. I haven't found
> such a feature in git, yet... but i think i am blind all the time.
> 

Most likely. I believe at least the reset command is mentioned in the 
tutorial. I trust you've read it before asking, so something is amiss 
either with your eyesight or the tutorial.


> I like git very much and every new day I like it more.
> 

It's a Good Thing. ;)

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

^ permalink raw reply

* Re: several quick questions
From: Linus Torvalds @ 2006-02-14 17:05 UTC (permalink / raw)
  To: Nicolas Vilz 'niv'; +Cc: git
In-Reply-To: <43F20532.5000609@iaglans.de>



On Tue, 14 Feb 2006, Nicolas Vilz 'niv' wrote:
> 
> i wonder, how i revoke a straight forward merge of two trees... I
> actually wanted to be look like somewhere in the git-repository, where
> some branches are merged back with the master tree, but i think, that
> wasn't "cg-merge -c <tree to merge with the actual one>"...
> 
> my result was that my master tree has now the same sha1-sum as my
> development-tree and gitk visualisation differs from that what i saw in
> the git-repository. (Several Arrows headed into back into one line...)
> 
> maybe that was because i didn't do anything in my master tree in the
> meantime.
> 
> And another thing, is there no posibility to get back to some commits or
> tags? I realized you can rebranch tags... what, if i want to switch back
> to git version 1.1.6 in the git repository? Or a certain commit?

Both of these can be solved with "git reset".

Before going into any more detail on that, let's go over the other related 
"basic operations" too:

 - "git branch". This creates a new branch of development at an arbitrary 
   point (that defaults to "current state").

   Example:

	git branch development-trial v1.1.6

   This will create a new branch called "development-trial", which starts 
   at the v1.1.6 state. NOTE! It will _not_ check it out - your old active 
   state is left totally alone, and you still stay on whatever branch you 
   used to be on.

 - "git checkout". This switches to another branch. As a shorthand, you 
   can also choose to create the branch at the same time, but normally 
   you'd just do like this example:

	git checkout development-trial

   which will switch to the branch you just created and check that out.

 - "git reset". This will reset the current branch state to something 
   else. This is what you would use if you want to undo a commit, 
   for example: you can "reset" the current branch to before the commit 
   happened.

   NOTE! When you do this, you also have to choose what you want to do 
   about your checked-out working tree. For example, when undoing the last 
   commit, you normally want to totally undo all the working tree changes 
   too, but you might also want to just undo the commit, and leave the 
   actual changes you committed alone, so that you can re-commit them with 
   a fixed commit message, for example.

   Example:

	git reset --hard HEAD^

   this will undo the last commit (more exactly: it will select the first 
   parent of HEAD to be the new top-of-development, so if the last thing 
   you did was a merge, it will reset to the previous state). The "--hard" 
   means that you want to reset the working tree too.

   Other example:

	git reset --hard v1.1.6

   This will just reset the current branch to a particular known state (ie 
   1.1.6 in this case).

   Without the "--hard", it will _not_ change the working tree, but just 
   update the index (and branch pointer, of course) to the new state, and 
   tell you which files are "dirty" in that new state. This is great for 
   undoing just a "git commit", but leaving the tree in the state is was 
   before you committed. It's not so great if you expected to revert 
   everything, and are now confused because "git diff" shows lots of 
   changes ;)

Finally, let's go over the difference between "git fetch" and "git pull":

 - "git fetch" is what you want to do if you want to _update_ another 
   branch. For example, if you want to track what Junio is doing in his 
   git repository (assuming that was what you cloned for), doing

	git fetch origin

   will update the "origin" branch, but will _not_ touch the current 
   branch itself. This is very useful for seeing what Junio has been 
   doing, without actually affecting your own work in any way.

 - "git pull" is really just "git fetch" + "git merge". It will fetch the 
   state you asked for, and then merge that into your current branch. So 
   it's important to rmember that this actually _changes_ what you have 
   checked out and have worked on. 

   One very special case of "git pull" is when you only use the repository 
   to track another branch, and you never do any changes at all, and you 
   never switch branches around, and you always pull from the same source. 
   In that case, "git pull" will basically boil down to just a read-only 
   tracking mechanism (ie you could think of this particular usage as 
   being the git equivalent of "anoncvs" access)

The reason people may get confused is that they start out using "git pull" 
as a read-only tracking mechanism, and it's not necessarily obvious that 
"git pull" really fundamentally is a very powerful operations - much MUCH 
more complex and powerful than just "track that other branch". Which is 
why I try to make the distinction between "git fetch" and "git pull" 
clear.

			Linus

^ 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