Git development
 help / color / mirror / Atom feed
* Re: [PATCH 1/3 v2] Implement the patience diff algorithm
From: Johannes Schindelin @ 2009-01-02 21:59 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Pierre Habouzit, davidel, Francis Galiegue, Git ML
In-Reply-To: <alpine.DEB.1.00.0901022220380.27818@racer>

Hi,

The interdiff between v1 and v2 of PATCH 1/3.  As you can see, I also 
added a cleanup of an intermediate xdlenv.

Ciao,
Dscho

 xdiff/xpatience.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/xdiff/xpatience.c b/xdiff/xpatience.c
index 6687940..d01cbdd 100644
--- a/xdiff/xpatience.c
+++ b/xdiff/xpatience.c
@@ -309,6 +309,8 @@ static int fall_back_to_classic_diff(struct hashmap *map,
 	memcpy(map->env->xdf1.rchg + line1 - 1, env.xdf1.rchg, count1);
 	memcpy(map->env->xdf2.rchg + line2 - 1, env.xdf2.rchg, count2);
 
+	xdl_free_env(&env);
+
 	return 0;
 }
 
@@ -368,6 +370,15 @@ int xdl_do_patience_diff(mmfile_t *file1, mmfile_t *file2,
 	if (xdl_prepare_env(file1, file2, xpp, env) < 0)
 		return -1;
 
+	/*
+	 * It is a pity that xdl_cleanup_records() not only marks those
+	 * lines as changes that are only present in one file, but also
+	 * lines that have multiple matches and happen to be in a "run
+	 * of discardable lines" that patience diff happens to split
+	 * differently.
+	 */
+	memset(env->xdf1.rchg, 0, env->xdf1.nrec);
+	memset(env->xdf2.rchg, 0, env->xdf2.nrec);
 	/* environment is cleaned up in xdl_diff() */
 	return patience_diff(file1, file2, xpp, env,
 			1, env->xdf1.nrec, 1, env->xdf2.nrec);
-- 
1.6.1.rc3.224.g95ac9

^ permalink raw reply related

* Re: [PATCH 2/3] unpack-trees: fix path search bug in verify_absent
From: Johannes Schindelin @ 2009-01-02 21:59 UTC (permalink / raw)
  To: Clemens Buchacher; +Cc: git, Miklos Vajna, gitster
In-Reply-To: <1230843273-11056-3-git-send-email-drizzd@aon.at>



On Thu, 1 Jan 2009, Clemens Buchacher wrote:

> Commit 0cf73755 (unpack-trees.c: assume submodules are clean during
> check-out) changed an argument to verify_absent from 'path' to 'ce',
> which is however shadowed by a local variable of the same name.
> 
> The bug triggers if verify_absent is used on a tree entry, for which
> the index contains one or more subsequent directories of the same
> length. The affected subdirectories are removed from the index. The
> testcase included in this commit bisects to 55218834 (checkout: do not
> lose staged removal), which reveals the bug in this case, but is
> otherwise unrelated.
> ---

Sign-off?

Just for the record, this patch fixes the testcase Miklos reported 
earlier.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH 2/3] unpack-trees: fix path search bug in verify_absent
From: Johannes Schindelin @ 2009-01-02 21:59 UTC (permalink / raw)
  To: Clemens Buchacher; +Cc: git, gitster
In-Reply-To: <1230843273-11056-3-git-send-email-drizzd@aon.at>

Hi,

On Thu, 1 Jan 2009, Clemens Buchacher wrote:

> Commit 0cf73755 (unpack-trees.c: assume submodules are clean during
> check-out) changed an argument to verify_absent from 'path' to 'ce',
> which is however shadowed by a local variable of the same name.

This explanation makes sense.  However, this:

> @@ -289,7 +289,8 @@ static int unpack_nondirectories(int n, unsigned long mask, unsigned long dirmas
>  	return 0;
>  }
>  
> -static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, struct name_entry *names, struct traverse_info *info)
> +static int unpack_callback(int n, unsigned long mask, unsigned long dirmask,
> +		struct name_entry *names, struct traverse_info *info)
>  {
>  	struct cache_entry *src[5] = { NULL, };
>  	struct unpack_trees_options *o = info->data;

... is distracting during review, and this:

> @@ -517,22 +518,22 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
>  	namelen = strlen(ce->name);
>  	pos = index_name_pos(o->src_index, ce->name, namelen);
>  	if (0 <= pos)
> -		return cnt; /* we have it as nondirectory */
> +		return 0; /* we have it as nondirectory */
>  	pos = -pos - 1;
>  	for (i = pos; i < o->src_index->cache_nr; i++) {

... is not accounted for in the commit message.  Intended or not, that is 
the question.

Ciao,
Dscho "whether 'tis noble"

^ permalink raw reply

* Re: [PATCH] Documentation/git-bundle.txt: Dumping contents of any bundle
From: jidanni @ 2009-01-02 22:03 UTC (permalink / raw)
  To: peff; +Cc: spearce, johannes.schindelin, nico, gitster, mdl123, git
In-Reply-To: <20090102082709.GA3498@coredump.intra.peff.net>

Some options are:

1) just add a line or two to my man page patch showing
what recovery can and can't presently be done. (No need for my
temporary file, use a pipe too.)

2) Also implement that step where everything is uncompressed and put
into lost+found, and document that they should expect to just see a
lot of connector markings, and if there are useful strings in there
then they are just lucky. We did the job asked: recovered to the best
extent of what they gave us.

JK> So I am inclined to leave it as-is: a patch in the list archive. If and
JK> when the day comes when somebody loses some super-important data and
JK> somehow matches all of these criteria, then they can consult whatever
JK> aged and senile git gurus still exist to pull the patch out and see if
JK> anything can be recovered.

I've read too many cases in RISKS Digest, news:comp.risks, about years
later organizations trying to recover some weird format or media.
Therefore I urge you to strike while the iron is hot and hook up the
function into the code.

Maybe some have never tried to recover data, but for those that one
day might, they will be thanking you over and over for taking this
opportunity to give them a chance. In many cases the few shreds they
can recover might be all they need.

Also one can see the innards of git -- no more black box.

If I were creating a new binary format, I would be sure to also
provide decoder tools. Otherwise it is just like it requires its own
proprietary environment to reveal any of its innards. Sure, you can
say well that data is mainly useless... but it is better than nothing
-- we did the best with what they gave us.

^ permalink raw reply

* Re: [PATCH v2 1/3] rebase: learn to rebase root commit
From: Thomas Rast @ 2009-01-02 22:20 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v4p0iivwh.fsf@gitster.siamese.dyndns.org>

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

Junio C Hamano wrote:
> Thomas Rast <trast@student.ethz.ch> writes:
> > The main use-case is with git-svn: [...]
> 
> I like what this series tries to do.  Using the --root option is probably
> a more natural way to do what people often do with the "add graft and
> filter-branch the whole history once" procedure.

Their uses are somewhat disjoint, as grafting only works if the
grafted parent has an empty tree.  Otherwise the grafted child will
appear to revert the entire history leading to it.  Rebase OTOH
changes the committers.

> But it somewhat feels sad if the "main" use-case for this is to start your
> project in git and then migrate away by feeding your history to subversion
> ;-).

You can remove that paragraph if you don't want to "support" SVN in
git.git ;-)

> >  # Make sure the branch to rebase onto is valid.
> >  onto_name=${newbase-"$upstream_name"}
> >  onto=$(git rev-parse --verify "${onto_name}^0") || exit
> >  
> >  # If a hook exists, give it a chance to interrupt
> > -run_pre_rebase_hook ${1+"$@"}
> > +run_pre_rebase_hook ${upstream_name+"$upstream_name"} "$@"
> 
> I do not think ${upstream_name+"$upstream_name"} is a good check to begin
> with, because presense of it does not necessarily mean the command was
> invoked without --root; it could have come from the environment of the
> invoker (hence the suggestion to unset the variable explicitly).

Good catch, thanks.

I'm still not sure what ${1+"$@"} was about by the way.  The most
authoritative reference I can find is

  http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_05_02

which says

  If there are no positional parameters, the expansion of '@' shall
  generate zero fields, even when '@' is double-quoted.

('man bash' agrees.)

> And I do not think this is a good way to extend the calling convention of
> the hook, either.  pre-rebase-hook used to always take upstream and
> optionally the explicit branch name.  When --root is given, your code will
> give the hook a single parameter which is the explicit branch name
> (i.e. "we will switch to this branch and rebase it, are you Ok with it?"),
> but the hook will mistakenly think you are feeding the fork-point commit.
> 
> Because an old pre-rebase-hook cannot verify --root case correctly anyway
> and needs to be updated, how about doing 'run_pre_rebase_hook --root "$@"'
> when --root was given?

True.  I noticed that I had to fix the positionals, but forgot about
the hook afterwards.  v3 implements this as you suggested.

> > +if test ! -z "$rebase_root"; then
> > +	revisions="$orig_head"
> > +	fp_flag="--root"
> > +else
> > +	revisions="$upstream..$orig_head"
> > +	fp_flag="--ignore-if-in-upstream"
> > +fi
> 
> Hmph, the reason why --ignore-if-in-upstream is irrelevant when --root is
> given is because...?

Well, originally because format-patch didn't like the argument.
Thanks for prodding however, $onto..$head makes sort of makes sense
here and I discovered that even $onto...$head works, which is used in
'rebase -i'.

However, it's still a change of semantics: With --root we now ignore
patches that are already contained in $onto, as opposed to patches
that were already in $upstream in normal operation.  It seems sensible
to do it this way, and perhaps even normal rebase should do it the
same way... if only format-patch would support it.

Thanks for the review! v3 upcoming.

-- 
Thomas Rast
trast@{inf,student}.ethz.ch


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* [PATCH v3 1/4] rebase -i: execute hook only after argument checking
From: Thomas Rast @ 2009-01-02 22:28 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, bss
In-Reply-To: <200901022320.14055.trast@student.ethz.ch>

Previously, the pre-rebase-hook would be launched before we knew if
the <upstream> [<branch>] arguments were supplied.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---

This is a quick fix and not really part of the series.  2/4 textually
depends on it, however, so I'm sending it along.

 git-rebase--interactive.sh |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index c8b0861..2c668cd 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -554,7 +554,6 @@ first and then run 'git rebase --continue' again."
 		;;
 	--)
 		shift
-		run_pre_rebase_hook ${1+"$@"}
 		test $# -eq 1 -o $# -eq 2 || usage
 		test -d "$DOTEST" &&
 			die "Interactive rebase already started"
@@ -562,11 +561,13 @@ first and then run 'git rebase --continue' again."
 		git var GIT_COMMITTER_IDENT >/dev/null ||
 			die "You need to set your committer info first"
 
+		UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
+		run_pre_rebase_hook ${1+"$@"}
+
 		comment_for_reflog start
 
 		require_clean_work_tree
 
-		UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
 		test -z "$ONTO" && ONTO=$UPSTREAM
 
 		if test ! -z "$2"
-- 
1.6.1.71.gaaa47.dirty

^ permalink raw reply related

* [PATCH v3 4/4] rebase: update documentation for --root
From: Thomas Rast @ 2009-01-02 22:28 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, bss
In-Reply-To: <6a754e4198413c4051a6085c5e5baab163835463.1230935095.git.trast@student.ethz.ch>

Since the new option depends on --onto and omission of <upstream>, use
a separate invocation style, and omit most options to save space.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 Documentation/git-rebase.txt |   21 ++++++++++++++++-----
 1 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index c8ad86a..3d6d429 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -8,10 +8,11 @@ git-rebase - Forward-port local commits to the updated upstream head
 SYNOPSIS
 --------
 [verse]
-'git rebase' [-i | --interactive] [-v | --verbose] [-m | --merge]
-	[-s <strategy> | --strategy=<strategy>] [--no-verify]
-	[-C<n>] [ --whitespace=<option>] [-p | --preserve-merges]
-	[--onto <newbase>] <upstream> [<branch>]
+'git rebase' [-i | --interactive] [options] [--onto <newbase>]
+	<upstream> [<branch>]
+'git rebase' [-i | --interactive] [options] --onto <newbase>
+	--root [<branch>]
+
 'git rebase' --continue | --skip | --abort
 
 DESCRIPTION
@@ -22,7 +23,8 @@ it remains on the current branch.
 
 All changes made by commits in the current branch but that are not
 in <upstream> are saved to a temporary area.  This is the same set
-of commits that would be shown by `git log <upstream>..HEAD`.
+of commits that would be shown by `git log <upstream>..HEAD` (or
+`git log HEAD`, if --root is specified).
 
 The current branch is reset to <upstream>, or <newbase> if the
 --onto option was supplied.  This has the exact same effect as
@@ -255,6 +257,15 @@ OPTIONS
 --preserve-merges::
 	Instead of ignoring merges, try to recreate them.
 
+--root::
+	Rebase all commits reachable from <branch>, instead of
+	limiting them with an <upstream>.  This allows you to rebase
+	the root commit(s) on a branch.  Must be used with --onto, and
+	will skip changes already contained in <newbase> (instead of
+	<upstream>).  When used together with --preserve-merges, 'all'
+	root commits will be rewritten to have <newbase> as parent
+	instead.
+
 include::merge-strategies.txt[]
 
 NOTES
-- 
1.6.1.71.gaaa47.dirty

^ permalink raw reply related

* [PATCH v3 2/4] rebase: learn to rebase root commit
From: Thomas Rast @ 2009-01-02 22:28 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, bss
In-Reply-To: <6a754e4198413c4051a6085c5e5baab163835463.1230935095.git.trast@student.ethz.ch>

Teach git-rebase a new option --root, which instructs it to rebase the
entire history leading up to <branch>.  This option must be used with
--onto <newbase>, and causes commits that already exist in <newbase>
to be skipped.  (Normal operation skips commits that already exist in
<upstream> instead.)

The main use-case is with git-svn: suppose you start hacking (perhaps
offline) on a new project, but later notice you want to commit this
work to SVN.  You will have to rebase the entire history, including
the root commit, on a (possibly empty) commit coming from git-svn, to
establish a history connection.  This previously had to be done by
cherry-picking the root commit manually.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 git-rebase.sh          |   50 +++++++++++++++++++--------
 t/t3412-rebase-root.sh |   86 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 121 insertions(+), 15 deletions(-)
 create mode 100755 t/t3412-rebase-root.sh

diff --git a/git-rebase.sh b/git-rebase.sh
index ebd4df3..9437e51 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -3,7 +3,7 @@
 # Copyright (c) 2005 Junio C Hamano.
 #
 
-USAGE='[--interactive | -i] [-v] [--onto <newbase>] <upstream> [<branch>]'
+USAGE='[--interactive | -i] [-v] [--onto <newbase>] [<upstream>|--root] [<branch>]'
 LONG_USAGE='git-rebase replaces <branch> with a new branch of the
 same name.  When the --onto option is provided the new branch starts
 out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>
@@ -47,6 +47,7 @@ dotest="$GIT_DIR"/rebase-merge
 prec=4
 verbose=
 git_am_opt=
+rebase_root=
 
 continue_merge () {
 	test -n "$prev_head" || die "prev_head must be defined"
@@ -297,6 +298,9 @@ do
 	-C*)
 		git_am_opt="$git_am_opt $1"
 		;;
+	--root)
+		rebase_root=t
+		;;
 	-*)
 		usage
 		;;
@@ -344,17 +348,26 @@ case "$diff" in
 	;;
 esac
 
+if test -z "$rebase_root"; then
 # The upstream head must be given.  Make sure it is valid.
-upstream_name="$1"
-upstream=`git rev-parse --verify "${upstream_name}^0"` ||
-    die "invalid upstream $upstream_name"
+	upstream_name="$1"
+	shift
+	upstream=`git rev-parse --verify "${upstream_name}^0"` ||
+	die "invalid upstream $upstream_name"
+	unset root_flag
+else
+	test -z "$newbase" && die "--root must be used with --onto"
+	unset upstream_name
+	unset upstream
+	root_flag="--root"
+fi
 
 # Make sure the branch to rebase onto is valid.
 onto_name=${newbase-"$upstream_name"}
 onto=$(git rev-parse --verify "${onto_name}^0") || exit
 
 # If a hook exists, give it a chance to interrupt
-run_pre_rebase_hook ${1+"$@"}
+run_pre_rebase_hook $root_flag $upstream_name "$@"
 
 # If the branch to rebase is given, that is the branch we will rebase
 # $branch_name -- branch being rebased, or HEAD (already detached)
@@ -362,16 +375,16 @@ run_pre_rebase_hook ${1+"$@"}
 # $head_name -- refs/heads/<that-branch> or "detached HEAD"
 switch_to=
 case "$#" in
-2)
+1)
 	# Is it "rebase other $branchname" or "rebase other $commit"?
-	branch_name="$2"
-	switch_to="$2"
+	branch_name="$1"
+	switch_to="$1"
 
-	if git show-ref --verify --quiet -- "refs/heads/$2" &&
-	   branch=$(git rev-parse -q --verify "refs/heads/$2")
+	if git show-ref --verify --quiet -- "refs/heads/$1" &&
+	   branch=$(git rev-parse -q --verify "refs/heads/$1")
 	then
-		head_name="refs/heads/$2"
-	elif branch=$(git rev-parse -q --verify "$2")
+		head_name="refs/heads/$1"
+	elif branch=$(git rev-parse -q --verify "$1")
 	then
 		head_name="detached HEAD"
 	else
@@ -393,7 +406,8 @@ case "$#" in
 esac
 orig_head=$branch
 
-# Now we are rebasing commits $upstream..$branch on top of $onto
+# Now we are rebasing commits $upstream..$branch (or with --root,
+# everything leading up to $branch) on top of $onto
 
 # Check if we are already based on $onto with linear history,
 # but this should be done only when upstream and onto are the same.
@@ -429,10 +443,16 @@ then
 	exit 0
 fi
 
+if test ! -z "$rebase_root"; then
+	revisions="$onto..$orig_head"
+else
+	revisions="$upstream..$orig_head"
+fi
+
 if test -z "$do_merge"
 then
 	git format-patch -k --stdout --full-index --ignore-if-in-upstream \
-		"$upstream..$orig_head" |
+		$root_flag "$revisions" |
 	git am $git_am_opt --rebasing --resolvemsg="$RESOLVEMSG" &&
 	move_to_original_branch
 	ret=$?
@@ -455,7 +475,7 @@ echo "$orig_head" > "$dotest/orig-head"
 echo "$head_name" > "$dotest/head-name"
 
 msgnum=0
-for cmt in `git rev-list --reverse --no-merges "$upstream..$orig_head"`
+for cmt in `git rev-list --reverse --no-merges "$revisions"`
 do
 	msgnum=$(($msgnum + 1))
 	echo "$cmt" > "$dotest/cmt.$msgnum"
diff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh
new file mode 100755
index 0000000..1978512
--- /dev/null
+++ b/t/t3412-rebase-root.sh
@@ -0,0 +1,86 @@
+#!/bin/sh
+
+test_description='git rebase --root
+
+Tests if git rebase --root --onto <newparent> can rebase the root commit.
+'
+. ./test-lib.sh
+
+test_expect_success 'prepare repository' '
+	echo 1 > A &&
+	git add A &&
+	git commit -m 1 &&
+	echo 2 > A &&
+	git add A &&
+	git commit -m 2 &&
+	git symbolic-ref HEAD refs/heads/other &&
+	rm .git/index &&
+	echo 1 > A &&
+	git add A &&
+	git commit -m 1b &&
+	echo 3 > B &&
+	git add B &&
+	git commit -m 3 &&
+	echo 4 > B &&
+	git add B &&
+	git commit -m 4
+'
+
+test_expect_success 'rebase --root expects --onto' '
+	test_must_fail git rebase --root
+'
+
+test_expect_success 'setup pre-rebase hook' '
+	mkdir -p .git/hooks &&
+	cat >.git/hooks/pre-rebase <<EOF &&
+#!$SHELL_PATH
+echo "\$1,\$2" >.git/PRE-REBASE-INPUT
+EOF
+	chmod +x .git/hooks/pre-rebase
+'
+cat > expect <<EOF
+4
+3
+2
+1
+EOF
+
+test_expect_success 'rebase --root --onto <newbase>' '
+	git checkout -b work &&
+	git rebase --root --onto master &&
+	git log --pretty=tformat:"%s" > rebased &&
+	test_cmp expect rebased
+'
+
+test_expect_success 'pre-rebase got correct input (1)' '
+	test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,
+'
+
+test_expect_success 'rebase --root --onto <newbase> <branch>' '
+	git branch work2 other &&
+	git rebase --root --onto master work2 &&
+	git log --pretty=tformat:"%s" > rebased2 &&
+	test_cmp expect rebased2
+'
+
+test_expect_success 'pre-rebase got correct input (2)' '
+	test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,work2
+'
+
+test_expect_success 'setup pre-rebase hook that fails' '
+	mkdir -p .git/hooks &&
+	cat >.git/hooks/pre-rebase <<EOF &&
+#!$SHELL_PATH
+false
+EOF
+	chmod +x .git/hooks/pre-rebase
+'
+
+test_expect_success 'pre-rebase hook stops rebase' '
+	git checkout -b stops1 other &&
+	GIT_EDITOR=: test_must_fail git rebase --root --onto master &&
+	test "z$(git symbolic-ref HEAD)" = zrefs/heads/stops1
+	test 0 = $(git rev-list other...stops1 | wc -l)
+'
+
+test_done
-- 
1.6.1.71.gaaa47.dirty

^ permalink raw reply related

* [PATCH v3 3/4] rebase -i: learn to rebase root commit
From: Thomas Rast @ 2009-01-02 22:28 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, bss
In-Reply-To: <6a754e4198413c4051a6085c5e5baab163835463.1230935095.git.trast@student.ethz.ch>

Teach git-rebase -i a new option --root, which instructs it to rebase
the entire history leading up to <branch>.  This is mainly for
symmetry with ordinary git-rebase; it cannot be used to edit the root
commit in-place (it requires --onto <newbase>).  Commits that already
exist in <newbase> are skipped.

In the normal mode of operation, this is fairly straightforward.  We
run cherry-pick in a loop, and cherry-pick has supported picking the
root commit since f95ebf7 (Allow cherry-picking root commits,
2008-07-04).

In --preserve-merges mode, we track the mapping from old to rewritten
commits and use it to update the parent list of each commit.  In this
case, we define 'rebase -i -p --root --onto $onto $branch' to rewrite
the parent list of all root commit(s) on $branch to contain $onto
instead.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 git-rebase--interactive.sh |  109 +++++++++++++++++++++++++++++++------------
 t/t3412-rebase-root.sh     |  101 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 179 insertions(+), 31 deletions(-)

diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 2c668cd..14d3e38 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -27,6 +27,7 @@ continue           continue rebasing process
 abort              abort rebasing process and restore original branch
 skip               skip current patch and continue rebasing process
 no-verify          override pre-rebase hook from stopping the operation
+root               rebase all reachable commmits up to the root(s)
 "
 
 . git-sh-setup
@@ -44,6 +45,7 @@ STRATEGY=
 ONTO=
 VERBOSE=
 OK_TO_SKIP_PRE_REBASE=
+REBASE_ROOT=
 
 GIT_CHERRY_PICK_HELP="  After resolving the conflicts,
 mark the corrected paths with 'git add <paths>', and
@@ -154,6 +156,11 @@ pick_one () {
 	output git rev-parse --verify $sha1 || die "Invalid commit name: $sha1"
 	test -d "$REWRITTEN" &&
 		pick_one_preserving_merges "$@" && return
+	if test ! -z "$REBASE_ROOT"
+	then
+		output git cherry-pick "$@"
+		return
+	fi
 	parent_sha1=$(git rev-parse --verify $sha1^) ||
 		die "Could not get the parent of $sha1"
 	current_sha1=$(git rev-parse --verify HEAD)
@@ -197,7 +204,11 @@ pick_one_preserving_merges () {
 
 	# rewrite parents; if none were rewritten, we can fast-forward.
 	new_parents=
-	pend=" $(git rev-list --parents -1 $sha1 | cut -d' ' -f2-)"
+	pend=" $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)"
+	if test "$pend" = " "
+	then
+		pend=" root"
+	fi
 	while [ "$pend" != "" ]
 	do
 		p=$(expr "$pend" : ' \([^ ]*\)')
@@ -227,7 +238,9 @@ pick_one_preserving_merges () {
 			if test -f "$DROPPED"/$p
 			then
 				fast_forward=f
-				pend=" $(cat "$DROPPED"/$p)$pend"
+				replacement="$(cat "$DROPPED"/$p)"
+				test -z "$replacement" && replacement=root
+				pend=" $replacement$pend"
 			else
 				new_parents="$new_parents $p"
 			fi
@@ -443,6 +456,7 @@ get_saved_options () {
 	test -d "$REWRITTEN" && PRESERVE_MERGES=t
 	test -f "$DOTEST"/strategy && STRATEGY="$(cat "$DOTEST"/strategy)"
 	test -f "$DOTEST"/verbose && VERBOSE=t
+	test ! -s "$DOTEST"/upstream && REBASE_ROOT=t
 }
 
 while test $# != 0
@@ -547,6 +561,9 @@ first and then run 'git rebase --continue' again."
 	-i)
 		# yeah, we know
 		;;
+	--root)
+		REBASE_ROOT=t
+		;;
 	--onto)
 		shift
 		ONTO=$(git rev-parse --verify "$1") ||
@@ -554,28 +571,36 @@ first and then run 'git rebase --continue' again."
 		;;
 	--)
 		shift
-		test $# -eq 1 -o $# -eq 2 || usage
+		test ! -z "$REBASE_ROOT" -o $# -eq 1 -o $# -eq 2 || usage
 		test -d "$DOTEST" &&
 			die "Interactive rebase already started"
 
 		git var GIT_COMMITTER_IDENT >/dev/null ||
 			die "You need to set your committer info first"
 
-		UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
-		run_pre_rebase_hook ${1+"$@"}
+		if test -z "$REBASE_ROOT"
+		then
+			UPSTREAM_ARG="$1"
+			UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
+			test -z "$ONTO" && ONTO=$UPSTREAM
+			shift
+		else
+			UPSTREAM_ARG=--root
+			test -z "$ONTO" &&
+				die "You must specify --onto when using --root"
+		fi
+		run_pre_rebase_hook "$UPSTREAM_ARG" "$@"
 
 		comment_for_reflog start
 
 		require_clean_work_tree
 
-		test -z "$ONTO" && ONTO=$UPSTREAM
-
-		if test ! -z "$2"
+		if test ! -z "$1"
 		then
-			output git show-ref --verify --quiet "refs/heads/$2" ||
-				die "Invalid branchname: $2"
-			output git checkout "$2" ||
-				die "Could not checkout $2"
+			output git show-ref --verify --quiet "refs/heads/$1" ||
+				die "Invalid branchname: $1"
+			output git checkout "$1" ||
+				die "Could not checkout $1"
 		fi
 
 		HEAD=$(git rev-parse --verify HEAD) || die "No HEAD?"
@@ -599,12 +624,19 @@ first and then run 'git rebase --continue' again."
 			# This ensures that commits on merged, but otherwise
 			# unrelated side branches are left alone. (Think "X"
 			# in the man page's example.)
-			mkdir "$REWRITTEN" &&
-			for c in $(git merge-base --all $HEAD $UPSTREAM)
-			do
-				echo $ONTO > "$REWRITTEN"/$c ||
+			if test -z "$REBASE_ROOT"
+			then
+				mkdir "$REWRITTEN" &&
+				for c in $(git merge-base --all $HEAD $UPSTREAM)
+				do
+					echo $ONTO > "$REWRITTEN"/$c ||
+						die "Could not init rewritten commits"
+				done
+			else
+				mkdir "$REWRITTEN" &&
+				echo $ONTO > "$REWRITTEN"/root ||
 					die "Could not init rewritten commits"
-			done
+			fi
 			# No cherry-pick because our first pass is to determine
 			# parents to rewrite and skipping dropped commits would
 			# prematurely end our probe
@@ -614,12 +646,21 @@ first and then run 'git rebase --continue' again."
 			MERGES_OPTION="--no-merges --cherry-pick"
 		fi
 
-		SHORTUPSTREAM=$(git rev-parse --short $UPSTREAM)
 		SHORTHEAD=$(git rev-parse --short $HEAD)
 		SHORTONTO=$(git rev-parse --short $ONTO)
+		if test -z "$REBASE_ROOT"
+			# this is now equivalent to ! -z "$UPSTREAM"
+		then
+			SHORTUPSTREAM=$(git rev-parse --short $UPSTREAM)
+			REVISIONS=$UPSTREAM...$HEAD
+			SHORTREVISIONS=$SHORTUPSTREAM..$SHORTHEAD
+		else
+			REVISIONS=$ONTO...$HEAD
+			SHORTREVISIONS=$SHORTHEAD
+		fi
 		git rev-list $MERGES_OPTION --pretty=oneline --abbrev-commit \
 			--abbrev=7 --reverse --left-right --topo-order \
-			$UPSTREAM...$HEAD | \
+			$REVISIONS | \
 			sed -n "s/^>//p" | while read shortsha1 rest
 		do
 			if test t != "$PRESERVE_MERGES"
@@ -627,14 +668,19 @@ first and then run 'git rebase --continue' again."
 				echo "pick $shortsha1 $rest" >> "$TODO"
 			else
 				sha1=$(git rev-parse $shortsha1)
-				preserve=t
-				for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -f2-)
-				do
-					if test -f "$REWRITTEN"/$p -a \( $p != $UPSTREAM -o $sha1 = $first_after_upstream \)
-					then
-						preserve=f
-					fi
-				done
+				if test -z "$REBASE_ROOT"
+				then
+					preserve=t
+					for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)
+					do
+						if test -f "$REWRITTEN"/$p -a \( $p != $UPSTREAM -o $sha1 = $first_after_upstream \)
+						then
+							preserve=f
+						fi
+					done
+				else
+					preserve=f
+				fi
 				if test f = "$preserve"
 				then
 					touch "$REWRITTEN"/$sha1
@@ -648,11 +694,11 @@ first and then run 'git rebase --continue' again."
 		then
 			mkdir "$DROPPED"
 			# Save all non-cherry-picked changes
-			git rev-list $UPSTREAM...$HEAD --left-right --cherry-pick | \
+			git rev-list $REVISIONS --left-right --cherry-pick | \
 				sed -n "s/^>//p" > "$DOTEST"/not-cherry-picks
 			# Now all commits and note which ones are missing in
 			# not-cherry-picks and hence being dropped
-			git rev-list $UPSTREAM..$HEAD |
+			git rev-list $REVISIONS |
 			while read rev
 			do
 				if test -f "$REWRITTEN"/$rev -a "$(grep "$rev" "$DOTEST"/not-cherry-picks)" = ""
@@ -661,17 +707,18 @@ first and then run 'git rebase --continue' again."
 					# not worthwhile, we don't want to track its multiple heads,
 					# just the history of its first-parent for others that will
 					# be rebasing on top of it
-					git rev-list --parents -1 $rev | cut -d' ' -f2 > "$DROPPED"/$rev
+					git rev-list --parents -1 $rev | cut -d' ' -s -f2 > "$DROPPED"/$rev
 					short=$(git rev-list -1 --abbrev-commit --abbrev=7 $rev)
 					grep -v "^[a-z][a-z]* $short" <"$TODO" > "${TODO}2" ; mv "${TODO}2" "$TODO"
 					rm "$REWRITTEN"/$rev
 				fi
 			done
 		fi
+
 		test -s "$TODO" || echo noop >> "$TODO"
 		cat >> "$TODO" << EOF
 
-# Rebase $SHORTUPSTREAM..$SHORTHEAD onto $SHORTONTO
+# Rebase $SHORTREVISIONS onto $SHORTONTO
 #
 # Commands:
 #  p, pick = use commit
diff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh
index 1978512..cbf3414 100755
--- a/t/t3412-rebase-root.sh
+++ b/t/t3412-rebase-root.sh
@@ -67,6 +67,100 @@ test_expect_success 'pre-rebase got correct input (2)' '
 	test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,work2
 '
 
+test_expect_success 'rebase -i --root --onto <newbase>' '
+	git checkout -b work3 other &&
+	GIT_EDITOR=: git rebase -i --root --onto master &&
+	git log --pretty=tformat:"%s" > rebased3 &&
+	test_cmp expect rebased3
+'
+
+test_expect_success 'pre-rebase got correct input (3)' '
+	test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,
+'
+
+test_expect_success 'rebase -i --root --onto <newbase> <branch>' '
+	git branch work4 other &&
+	GIT_EDITOR=: git rebase -i --root --onto master work4 &&
+	git log --pretty=tformat:"%s" > rebased4 &&
+	test_cmp expect rebased4
+'
+
+test_expect_success 'pre-rebase got correct input (4)' '
+	test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,work4
+'
+
+test_expect_success 'rebase -i -p with linear history' '
+	git checkout -b work5 other &&
+	GIT_EDITOR=: git rebase -i -p --root --onto master &&
+	git log --pretty=tformat:"%s" > rebased5 &&
+	test_cmp expect rebased5
+'
+
+test_expect_success 'pre-rebase got correct input (5)' '
+	test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,
+'
+
+test_expect_success 'set up merge history' '
+	git checkout other^ &&
+	git checkout -b side &&
+	echo 5 > C &&
+	git add C &&
+	git commit -m 5 &&
+	git checkout other &&
+	git merge side
+'
+
+sed 's/#/ /g' > expect-side <<'EOF'
+*   Merge branch 'side' into other
+|\##
+| * 5
+* | 4
+|/##
+* 3
+* 2
+* 1
+EOF
+
+test_expect_success 'rebase -i -p with merge' '
+	git checkout -b work6 other &&
+	GIT_EDITOR=: git rebase -i -p --root --onto master &&
+	git log --graph --topo-order --pretty=tformat:"%s" > rebased6 &&
+	test_cmp expect-side rebased6
+'
+
+test_expect_success 'set up second root and merge' '
+	git symbolic-ref HEAD refs/heads/third &&
+	rm .git/index &&
+	rm A B C &&
+	echo 6 > D &&
+	git add D &&
+	git commit -m 6 &&
+	git checkout other &&
+	git merge third
+'
+
+sed 's/#/ /g' > expect-third <<'EOF'
+*   Merge branch 'third' into other
+|\##
+| * 6
+* |   Merge branch 'side' into other
+|\ \##
+| * | 5
+* | | 4
+|/ /##
+* | 3
+|/##
+* 2
+* 1
+EOF
+
+test_expect_success 'rebase -i -p with two roots' '
+	git checkout -b work7 other &&
+	GIT_EDITOR=: git rebase -i -p --root --onto master &&
+	git log --graph --topo-order --pretty=tformat:"%s" > rebased7 &&
+	test_cmp expect-third rebased7
+'
+
 test_expect_success 'setup pre-rebase hook that fails' '
 	mkdir -p .git/hooks &&
 	cat >.git/hooks/pre-rebase <<EOF &&
@@ -83,4 +177,11 @@ test_expect_success 'pre-rebase hook stops rebase' '
 	test 0 = $(git rev-list other...stops1 | wc -l)
 '
 
+test_expect_success 'pre-rebase hook stops rebase -i' '
+	git checkout -b stops2 other &&
+	GIT_EDITOR=: test_must_fail git rebase --root --onto master &&
+	test "z$(git symbolic-ref HEAD)" = zrefs/heads/stops2
+	test 0 = $(git rev-list other...stops2 | wc -l)
+'
+
 test_done
-- 
1.6.1.71.gaaa47.dirty

^ permalink raw reply related

* Re: "git reset --hard" == "git checkout HEAD" == "git reset --hard HEAD" ???
From: Junio C Hamano @ 2009-01-02 22:36 UTC (permalink / raw)
  To: chris; +Cc: git
In-Reply-To: <20090102195724.GA23119@seberino.org>

chris@seberino.org writes:

> Does "git reset --hard" == "git checkout HEAD" == "git reset --hard HEAD" ???

No, but "reset --hard" without a commit-ish defaults to HEAD so the first
one and the last one are equivalent.

> It seems we have 2 ways to blow away work we haven't checked in yet then right?

Wrong.

^ permalink raw reply

* [INTERDIFF v3 2/4] rebase: learn to rebase root commit
From: Thomas Rast @ 2009-01-02 22:41 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, bss
In-Reply-To: <7c74d8be216b4667f470e34644c4aa26dcfe0cfb.1230935095.git.trast@student.ethz.ch>

The interdiff to v2.

diff --git a/git-rebase.sh b/git-rebase.sh
index 89de3c4..9437e51 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -354,17 +354,20 @@ if test -z "$rebase_root"; then
 	shift
 	upstream=`git rev-parse --verify "${upstream_name}^0"` ||
 	die "invalid upstream $upstream_name"
+	unset root_flag
+else
+	test -z "$newbase" && die "--root must be used with --onto"
+	unset upstream_name
+	unset upstream
+	root_flag="--root"
 fi
 
-test ! -z "$rebase_root" -a -z "$newbase" &&
-	die "--root must be used with --onto"
-
 # Make sure the branch to rebase onto is valid.
 onto_name=${newbase-"$upstream_name"}
 onto=$(git rev-parse --verify "${onto_name}^0") || exit
 
 # If a hook exists, give it a chance to interrupt
-run_pre_rebase_hook ${upstream_name+"$upstream_name"} "$@"
+run_pre_rebase_hook $root_flag $upstream_name "$@"
 
 # If the branch to rebase is given, that is the branch we will rebase
 # $branch_name -- branch being rebased, or HEAD (already detached)
@@ -403,8 +406,8 @@ case "$#" in
 esac
 orig_head=$branch
 
-# Now we are rebasing commits $upstream..$branch (or simply $branch
-# with --root) on top of $onto
+# Now we are rebasing commits $upstream..$branch (or with --root,
+# everything leading up to $branch) on top of $onto
 
 # Check if we are already based on $onto with linear history,
 # but this should be done only when upstream and onto are the same.
@@ -441,17 +444,15 @@ then
 fi
 
 if test ! -z "$rebase_root"; then
-	revisions="$orig_head"
-	fp_flag="--root"
+	revisions="$onto..$orig_head"
 else
 	revisions="$upstream..$orig_head"
-	fp_flag="--ignore-if-in-upstream"
 fi
 
 if test -z "$do_merge"
 then
-	git format-patch -k --stdout --full-index "$fp_flag" \
-		"$revisions" |
+	git format-patch -k --stdout --full-index --ignore-if-in-upstream \
+		$root_flag "$revisions" |
 	git am $git_am_opt --rebasing --resolvemsg="$RESOLVEMSG" &&
 	move_to_original_branch
 	ret=$?
diff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh
index 63ec5e6..1978512 100755
--- a/t/t3412-rebase-root.sh
+++ b/t/t3412-rebase-root.sh
@@ -15,7 +15,9 @@ test_expect_success 'prepare repository' '
 	git commit -m 2 &&
 	git symbolic-ref HEAD refs/heads/other &&
 	rm .git/index &&
-	rm A &&
+	echo 1 > A &&
+	git add A &&
+	git commit -m 1b &&
 	echo 3 > B &&
 	git add B &&
 	git commit -m 3 &&
@@ -28,6 +30,14 @@ test_expect_success 'rebase --root expects --onto' '
 	test_must_fail git rebase --root
 '
 
+test_expect_success 'setup pre-rebase hook' '
+	mkdir -p .git/hooks &&
+	cat >.git/hooks/pre-rebase <<EOF &&
+#!$SHELL_PATH
+echo "\$1,\$2" >.git/PRE-REBASE-INPUT
+EOF
+	chmod +x .git/hooks/pre-rebase
+'
 cat > expect <<EOF
 4
 3
@@ -42,6 +52,10 @@ test_expect_success 'rebase --root --onto <newbase>' '
 	test_cmp expect rebased
 '
 
+test_expect_success 'pre-rebase got correct input (1)' '
+	test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,
+'
+
 test_expect_success 'rebase --root --onto <newbase> <branch>' '
 	git branch work2 other &&
 	git rebase --root --onto master work2 &&
@@ -49,4 +63,24 @@ test_expect_success 'rebase --root --onto <newbase> <branch>' '
 	test_cmp expect rebased2
 '
 
+test_expect_success 'pre-rebase got correct input (2)' '
+	test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,work2
+'
+
+test_expect_success 'setup pre-rebase hook that fails' '
+	mkdir -p .git/hooks &&
+	cat >.git/hooks/pre-rebase <<EOF &&
+#!$SHELL_PATH
+false
+EOF
+	chmod +x .git/hooks/pre-rebase
+'
+
+test_expect_success 'pre-rebase hook stops rebase' '
+	git checkout -b stops1 other &&
+	GIT_EDITOR=: test_must_fail git rebase --root --onto master &&
+	test "z$(git symbolic-ref HEAD)" = zrefs/heads/stops1
+	test 0 = $(git rev-list other...stops1 | wc -l)
+'
+
 test_done

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

^ permalink raw reply related

* [INTERDIFF v3 3/4] rebase -i: learn to rebase root commit
From: Thomas Rast @ 2009-01-02 22:41 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, bss
In-Reply-To: <43e09eaf2b9a9a3805b9262957ece32190ae4c32.1230935095.git.trast@student.ethz.ch>

This is the interdiff to v2.  Some of the changes are noise from 1/4.

diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index d6f54eb..14d3e38 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -238,7 +238,9 @@ pick_one_preserving_merges () {
 			if test -f "$DROPPED"/$p
 			then
 				fast_forward=f
-				pend=" $(cat "$DROPPED"/$p)$pend"
+				replacement="$(cat "$DROPPED"/$p)"
+				test -z "$replacement" && replacement=root
+				pend=" $replacement$pend"
 			else
 				new_parents="$new_parents $p"
 			fi
@@ -569,7 +571,6 @@ first and then run 'git rebase --continue' again."
 		;;
 	--)
 		shift
-		run_pre_rebase_hook ${1+"$@"}
 		test ! -z "$REBASE_ROOT" -o $# -eq 1 -o $# -eq 2 || usage
 		test -d "$DOTEST" &&
 			die "Interactive rebase already started"
@@ -577,19 +578,22 @@ first and then run 'git rebase --continue' again."
 		git var GIT_COMMITTER_IDENT >/dev/null ||
 			die "You need to set your committer info first"
 
-		comment_for_reflog start
-
-		require_clean_work_tree
-
 		if test -z "$REBASE_ROOT"
 		then
+			UPSTREAM_ARG="$1"
 			UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
 			test -z "$ONTO" && ONTO=$UPSTREAM
 			shift
 		else
+			UPSTREAM_ARG=--root
 			test -z "$ONTO" &&
 				die "You must specify --onto when using --root"
 		fi
+		run_pre_rebase_hook "$UPSTREAM_ARG" "$@"
+
+		comment_for_reflog start
+
+		require_clean_work_tree
 
 		if test ! -z "$1"
 		then
@@ -651,7 +655,7 @@ first and then run 'git rebase --continue' again."
 			REVISIONS=$UPSTREAM...$HEAD
 			SHORTREVISIONS=$SHORTUPSTREAM..$SHORTHEAD
 		else
-			REVISIONS=$HEAD
+			REVISIONS=$ONTO...$HEAD
 			SHORTREVISIONS=$SHORTHEAD
 		fi
 		git rev-list $MERGES_OPTION --pretty=oneline --abbrev-commit \
@@ -710,6 +714,7 @@ first and then run 'git rebase --continue' again."
 				fi
 			done
 		fi
+
 		test -s "$TODO" || echo noop >> "$TODO"
 		cat >> "$TODO" << EOF
 
diff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh
index c845dfc..cbf3414 100755
--- a/t/t3412-rebase-root.sh
+++ b/t/t3412-rebase-root.sh
@@ -15,7 +15,9 @@ test_expect_success 'prepare repository' '
 	git commit -m 2 &&
 	git symbolic-ref HEAD refs/heads/other &&
 	rm .git/index &&
-	rm A &&
+	echo 1 > A &&
+	git add A &&
+	git commit -m 1b &&
 	echo 3 > B &&
 	git add B &&
 	git commit -m 3 &&
@@ -28,6 +30,14 @@ test_expect_success 'rebase --root expects --onto' '
 	test_must_fail git rebase --root
 '
 
+test_expect_success 'setup pre-rebase hook' '
+	mkdir -p .git/hooks &&
+	cat >.git/hooks/pre-rebase <<EOF &&
+#!$SHELL_PATH
+echo "\$1,\$2" >.git/PRE-REBASE-INPUT
+EOF
+	chmod +x .git/hooks/pre-rebase
+'
 cat > expect <<EOF
 4
 3
@@ -42,6 +52,10 @@ test_expect_success 'rebase --root --onto <newbase>' '
 	test_cmp expect rebased
 '
 
+test_expect_success 'pre-rebase got correct input (1)' '
+	test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,
+'
+
 test_expect_success 'rebase --root --onto <newbase> <branch>' '
 	git branch work2 other &&
 	git rebase --root --onto master work2 &&
@@ -49,6 +63,10 @@ test_expect_success 'rebase --root --onto <newbase> <branch>' '
 	test_cmp expect rebased2
 '
 
+test_expect_success 'pre-rebase got correct input (2)' '
+	test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,work2
+'
+
 test_expect_success 'rebase -i --root --onto <newbase>' '
 	git checkout -b work3 other &&
 	GIT_EDITOR=: git rebase -i --root --onto master &&
@@ -56,6 +74,10 @@ test_expect_success 'rebase -i --root --onto <newbase>' '
 	test_cmp expect rebased3
 '
 
+test_expect_success 'pre-rebase got correct input (3)' '
+	test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,
+'
+
 test_expect_success 'rebase -i --root --onto <newbase> <branch>' '
 	git branch work4 other &&
 	GIT_EDITOR=: git rebase -i --root --onto master work4 &&
@@ -63,6 +85,10 @@ test_expect_success 'rebase -i --root --onto <newbase> <branch>' '
 	test_cmp expect rebased4
 '
 
+test_expect_success 'pre-rebase got correct input (4)' '
+	test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,work4
+'
+
 test_expect_success 'rebase -i -p with linear history' '
 	git checkout -b work5 other &&
 	GIT_EDITOR=: git rebase -i -p --root --onto master &&
@@ -70,6 +96,10 @@ test_expect_success 'rebase -i -p with linear history' '
 	test_cmp expect rebased5
 '
 
+test_expect_success 'pre-rebase got correct input (5)' '
+	test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,
+'
+
 test_expect_success 'set up merge history' '
 	git checkout other^ &&
 	git checkout -b side &&
@@ -131,4 +161,27 @@ test_expect_success 'rebase -i -p with two roots' '
 	test_cmp expect-third rebased7
 '
 
+test_expect_success 'setup pre-rebase hook that fails' '
+	mkdir -p .git/hooks &&
+	cat >.git/hooks/pre-rebase <<EOF &&
+#!$SHELL_PATH
+false
+EOF
+	chmod +x .git/hooks/pre-rebase
+'
+
+test_expect_success 'pre-rebase hook stops rebase' '
+	git checkout -b stops1 other &&
+	GIT_EDITOR=: test_must_fail git rebase --root --onto master &&
+	test "z$(git symbolic-ref HEAD)" = zrefs/heads/stops1
+	test 0 = $(git rev-list other...stops1 | wc -l)
+'
+
+test_expect_success 'pre-rebase hook stops rebase -i' '
+	git checkout -b stops2 other &&
+	GIT_EDITOR=: test_must_fail git rebase --root --onto master &&
+	test "z$(git symbolic-ref HEAD)" = zrefs/heads/stops2
+	test 0 = $(git rev-list other...stops2 | wc -l)
+'
+
 test_done

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

^ permalink raw reply related

* Re: how to track the history of a line in a file
From: david @ 2009-01-02 23:48 UTC (permalink / raw)
  To: Jeff King; +Cc: git
In-Reply-To: <alpine.DEB.1.10.0901021459480.21567@asgard.lang.hm>

On Fri, 2 Jan 2009, david@lang.hm wrote:

> On Fri, 2 Jan 2009, Jeff King wrote:
>
>> The tricky thing here is what is "this line"? Using the line number
>> isn't right, since it will change based on other content coming in and
>> out of the file. You can keep drilling down by reblaming parent commits,
>> but remember that each time you do that you are manually looking at the
>> content and saying "Oh, this is the line I am still interested in." So I
>> a script would have to correlate the old version and new version of the
>> line and realize how to follow the "interesting" thing.
>> 
>> In your case, I think you want to see any commit in Makefile which
>> changed a line with SUBLEVEL in it. Which is maybe easiest done as:
>>
>>  git log -z -p Makefile |
>>    perl -0ne 'print if /\n[+-]SUBLEVEL/' |
>>    tr '\0' '\n'
>> 
>> and is pretty fast. But obviously we're leveraging some content-specific
>> knowledge about what's in the Makefile.
>
> Ok, I hacked togeather a quick bash script to try this
>
<SNIP>
> the problem that this has is that line 3 of $COMMIT may not be line 3 of 
> $COMMIT^, and if they aren't it ends up hunting down the wrong data
>
> either that or I am not understanding the output of git blame properly (also 
> very possible)

I was misunderstanding git blame

new script is

#!/bin/bash
line=`git blame -n -b -l -L /$1/,+1 -M $2`
echo "-$line"
foundCOMMIT=`echo "$line" |cut -c -40`
foundline=`echo "$line" |cut -c 42- |cut -f 1 -d " "`
while [ "$foundCOMMIT" != "                                        " ] ;do
#git diff -U0 $foundCOMMIT..$foundCOMMIT^ $2
line=`git blame -n -b -l -L $foundline,+1 -M $2 $foundCOMMIT^`
echo "-$line"
foundCOMMIT=`echo "$line" |cut -c -40`
foundline=`echo "$line" |cut -c 42- |cut -f 1 -d " "`
done

this seems to be working for me now.

David Lang

^ permalink raw reply

* Re: [PATCH v2 1/3] rebase: learn to rebase root commit
From: Junio C Hamano @ 2009-01-02 22:49 UTC (permalink / raw)
  To: Thomas Rast; +Cc: git
In-Reply-To: <200901022320.14055.trast@student.ethz.ch>

Thomas Rast <trast@student.ethz.ch> writes:

> I'm still not sure what ${1+"$@"} was about by the way.

It is one of the many old-timer's portability idioms that let us work
around bugs in some ancient shell implementations.

${1+"$@"} should be equivalent to "$@" in modern Bourne shell variants
that are POSIX compliant.

^ permalink raw reply

* Re: how to track the history of a line in a file
From: david @ 2009-01-02 23:56 UTC (permalink / raw)
  To: Jeff King; +Cc: git
In-Reply-To: <alpine.DEB.1.10.0901021544580.21567@asgard.lang.hm>

On Fri, 2 Jan 2009, david@lang.hm wrote:

> On Fri, 2 Jan 2009, david@lang.hm wrote:
>
>> On Fri, 2 Jan 2009, Jeff King wrote:
>> 
>>> The tricky thing here is what is "this line"? Using the line number
>>> isn't right, since it will change based on other content coming in and
>>> out of the file. You can keep drilling down by reblaming parent commits,
>>> but remember that each time you do that you are manually looking at the
>>> content and saying "Oh, this is the line I am still interested in." So I
>>> a script would have to correlate the old version and new version of the
>>> line and realize how to follow the "interesting" thing.
>>> 
>>> In your case, I think you want to see any commit in Makefile which
>>> changed a line with SUBLEVEL in it. Which is maybe easiest done as:
>>>
>>>  git log -z -p Makefile |
>>>    perl -0ne 'print if /\n[+-]SUBLEVEL/' |
>>>    tr '\0' '\n'
>>> 
>>> and is pretty fast. But obviously we're leveraging some content-specific
>>> knowledge about what's in the Makefile.
>> 
>> Ok, I hacked togeather a quick bash script to try this
>> 
> <SNIP>
>> the problem that this has is that line 3 of $COMMIT may not be line 3 of 
>> $COMMIT^, and if they aren't it ends up hunting down the wrong data
>> 
>> either that or I am not understanding the output of git blame properly 
>> (also very possible)
>
> I was misunderstanding git blame
>
> new script is
>
> #!/bin/bash
> line=`git blame -n -b -l -L /$1/,+1 -M $2`
> echo "-$line"
> foundCOMMIT=`echo "$line" |cut -c -40`
> foundline=`echo "$line" |cut -c 42- |cut -f 1 -d " "`
> while [ "$foundCOMMIT" != "                                        " ] ;do
> #git diff -U0 $foundCOMMIT..$foundCOMMIT^ $2
> line=`git blame -n -b -l -L $foundline,+1 -M $2 $foundCOMMIT^`
> echo "-$line"
> foundCOMMIT=`echo "$line" |cut -c -40`
> foundline=`echo "$line" |cut -c 42- |cut -f 1 -d " "`
> done
>
> this seems to be working for me now.

not quite, it works as long as the line doesn't move in the commit where 
it changes.

David Lang

^ permalink raw reply

* Re: [PATCH rfc v2] git-sh-setup: Fix scripts whose PWD is a symlink to a work-dir on OS X
From: Marcel Koeppen @ 2009-01-02 22:53 UTC (permalink / raw)
  To: git
In-Reply-To: <1230649824-1893-1-git-send-email-marcel@oak.homeunix.org>

Hi,

Am 30.12.2008 um 16:10 schrieb Marcel M. Cary:

> I sent the first rev of this patch to just Brian.  It didn't have
> either of the unit test changes.  He said it fixed all but t2300.3,
> where cd_to_toplevel doesn't actually "cd", so I made the same change
> to the unit test itself.  Can someone with OS X try running the test
> suite with v2 of this patch?  I don't have OS X readily available.

the patch fixes t2300-cd-to-toplevel and t5521-pull-symlink for me.

	Marcel

[I don't know why my replies get lost, so I dropped all individual  
recipients on this third try...]

^ permalink raw reply

* Re: [PATCH v2 1/3] rebase: learn to rebase root commit
From: Thomas Rast @ 2009-01-02 22:54 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vzli9b9y6.fsf@gitster.siamese.dyndns.org>

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

Junio C Hamano wrote:
> Thomas Rast <trast@student.ethz.ch> writes:
> 
> > I'm still not sure what ${1+"$@"} was about by the way.
> 
> It is one of the many old-timer's portability idioms that let us work
> around bugs in some ancient shell implementations.
> 
> ${1+"$@"} should be equivalent to "$@" in modern Bourne shell variants
> that are POSIX compliant.

So do you want me to change it back to ${1+"$@"}?

-- 
Thomas Rast
trast@{inf,student}.ethz.ch


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: how to track the history of a line in a file
From: Junio C Hamano @ 2009-01-02 22:54 UTC (permalink / raw)
  To: david; +Cc: Jeff King, git
In-Reply-To: <alpine.DEB.1.10.0901021544580.21567@asgard.lang.hm>

david@lang.hm writes:

> I was misunderstanding git blame

You may find the --porcelain output format of git-blame useful to make
your script safer and more robust.

^ permalink raw reply

* Re: [PATCH 0/3] Teach Git about the patience diff algorithm
From: Linus Torvalds @ 2009-01-02 23:05 UTC (permalink / raw)
  To: Jeff King
  Cc: Johannes Schindelin, Clemens Buchacher, Adeodato Simó,
	Pierre Habouzit, davidel, Francis Galiegue, Git ML
In-Reply-To: <20090102205208.GA9273@coredump.intra.peff.net>



On Fri, 2 Jan 2009, Jeff King wrote:
> 
> Here's another interesting one: d592b315. The commit removes dashes
> from git commands in test scripts. Git says:
> 
>         echo "tag-one-line" >expect &&
> -       git-tag -l | grep "^tag-one-line" >actual &&
> +       git tag -l | grep "^tag-one-line" >actual &&
>         test_cmp expect actual &&
> -       git-tag -n0 -l | grep "^tag-one-line" >actual &&
> +       git tag -n0 -l | grep "^tag-one-line" >actual &&
>         test_cmp expect actual &&
> -       git-tag -n0 -l tag-one-line >actual &&
> +       git tag -n0 -l tag-one-line >actual &&
>         test_cmp expect actual &&
> 
> whereas patience says:
> 
>         echo "tag-one-line" >expect &&
> -       git-tag -l | grep "^tag-one-line" >actual &&
> -       test_cmp expect actual &&
> -       git-tag -n0 -l | grep "^tag-one-line" >actual &&
> -       test_cmp expect actual &&
> -       git-tag -n0 -l tag-one-line >actual &&
> +       git tag -l | grep "^tag-one-line" >actual &&
> +       test_cmp expect actual &&
> +       git tag -n0 -l | grep "^tag-one-line" >actual &&
> +       test_cmp expect actual &&
> +       git tag -n0 -l tag-one-line >actual &&
>         test_cmp expect actual &&

Yeah, the bazaar version clearly is inferior here. But again, I don't 
think that's actually a patience diff issue, I think it's because the 
bazaar diff has merged consecutive diff lines too aggressively.

I suspect both patience and the straight Mayers diff (that git uses) 
actually finds exactly the same differences, and then bazaar has a "merge 
closeby -/ pairs together if there is just a single unmodified line in 
between them". 

And _that_ is where it should care whether the unmodified line is complex 
or not. If it's complex, you shouldn't merge it into the -/+ region.

(but yes, it's possible that the bazaar diff uses "uniqueness" as a 
complexity analysis marker, and while that is somewhat valid, it is _not_ 
valid enough to be useful. Unique lines tend to be complex, but complex 
lines are _not_ always unique)

		Linus

^ permalink raw reply

* Re: [PATCH v3 2/4] rebase: learn to rebase root commit
From: Junio C Hamano @ 2009-01-02 23:06 UTC (permalink / raw)
  To: Thomas Rast; +Cc: git, bss
In-Reply-To: <7c74d8be216b4667f470e34644c4aa26dcfe0cfb.1230935095.git.trast@student.ethz.ch>


>  # If a hook exists, give it a chance to interrupt
> -run_pre_rebase_hook ${1+"$@"}
> +run_pre_rebase_hook $root_flag $upstream_name "$@"

You'd have to quote the $upstream_name properly here, because the original
command line could well have been:

	$ git rebase 'master@{3 days ago}'

^ permalink raw reply

* Re: [PATCH v2 1/3] rebase: learn to rebase root commit
From: Junio C Hamano @ 2009-01-02 23:07 UTC (permalink / raw)
  To: Thomas Rast; +Cc: git
In-Reply-To: <200901022354.17922.trast@student.ethz.ch>

Thomas Rast <trast@student.ethz.ch> writes:

>> ${1+"$@"} should be equivalent to "$@" in modern Bourne shell variants
>> that are POSIX compliant.
>
> So do you want me to change it back to ${1+"$@"}?

No.  I was merely answering your question.

^ permalink raw reply

* [PATCH v3.1] rebase: learn to rebase root commit
From: Thomas Rast @ 2009-01-02 23:45 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano
In-Reply-To: <7vljttb95u.fsf@gitster.siamese.dyndns.org>

Teach git-rebase a new option --root, which instructs it to rebase the
entire history leading up to <branch>.  This option must be used with
--onto <newbase>, and causes commits that already exist in <newbase>
to be skipped.  (Normal operation skips commits that already exist in
<upstream> instead.)

The main use-case is with git-svn: suppose you start hacking (perhaps
offline) on a new project, but later notice you want to commit this
work to SVN.  You will have to rebase the entire history, including
the root commit, on a (possibly empty) commit coming from git-svn, to
establish a history connection.  This previously had to be done by
cherry-picking the root commit manually.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>

---

Junio C Hamano wrote:
> 
> >  # If a hook exists, give it a chance to interrupt
> > -run_pre_rebase_hook ${1+"$@"}
> > +run_pre_rebase_hook $root_flag $upstream_name "$@"
> 
> You'd have to quote the $upstream_name properly here, because the original
> command line could well have been:
> 
> 	$ git rebase 'master@{3 days ago}'

Right, thanks.  Let's fix it like this, so I won't have to look up
what the various special parameter expansion characters mean.
($root_flag is still used further below.)

>> --- a/git-rebase.sh
>> +++ b/git-rebase.sh
>> @@ -355,11 +355,13 @@ if test -z "$rebase_root"; then
>>         upstream=`git rev-parse --verify "${upstream_name}^0"` ||
>>         die "invalid upstream $upstream_name"
>>         unset root_flag
>> +       upstream_arg="$upstream_name"
>>  else
>>         test -z "$newbase" && die "--root must be used with --onto"
>>         unset upstream_name
>>         unset upstream
>>         root_flag="--root"
>> +       upstream_arg="$root_flag"
>>  fi
>>  
>>  # Make sure the branch to rebase onto is valid.
>> @@ -367,7 +369,7 @@ onto_name=${newbase-"$upstream_name"}
>>  onto=$(git rev-parse --verify "${onto_name}^0") || exit
>>  
>>  # If a hook exists, give it a chance to interrupt
>> -run_pre_rebase_hook $root_flag $upstream_name "$@"
>> +run_pre_rebase_hook "$upstream_arg" "$@"
>>  
>>  # If the branch to rebase is given, that is the branch we will rebase
>>  # $branch_name -- branch being rebased, or HEAD (already detached)

 git-rebase.sh          |   52 ++++++++++++++++++++--------
 t/t3412-rebase-root.sh |   86 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 123 insertions(+), 15 deletions(-)

diff --git a/git-rebase.sh b/git-rebase.sh
index ebd4df3..d1083f1 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -3,7 +3,7 @@
 # Copyright (c) 2005 Junio C Hamano.
 #
 
-USAGE='[--interactive | -i] [-v] [--onto <newbase>] <upstream> [<branch>]'
+USAGE='[--interactive | -i] [-v] [--onto <newbase>] [<upstream>|--root] [<branch>]'
 LONG_USAGE='git-rebase replaces <branch> with a new branch of the
 same name.  When the --onto option is provided the new branch starts
 out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>
@@ -47,6 +47,7 @@ dotest="$GIT_DIR"/rebase-merge
 prec=4
 verbose=
 git_am_opt=
+rebase_root=
 
 continue_merge () {
 	test -n "$prev_head" || die "prev_head must be defined"
@@ -297,6 +298,9 @@ do
 	-C*)
 		git_am_opt="$git_am_opt $1"
 		;;
+	--root)
+		rebase_root=t
+		;;
 	-*)
 		usage
 		;;
@@ -344,17 +348,28 @@ case "$diff" in
 	;;
 esac
 
+if test -z "$rebase_root"; then
 # The upstream head must be given.  Make sure it is valid.
-upstream_name="$1"
-upstream=`git rev-parse --verify "${upstream_name}^0"` ||
-    die "invalid upstream $upstream_name"
+	upstream_name="$1"
+	shift
+	upstream=`git rev-parse --verify "${upstream_name}^0"` ||
+	die "invalid upstream $upstream_name"
+	unset root_flag
+	upstream_arg="$upstream_name"
+else
+	test -z "$newbase" && die "--root must be used with --onto"
+	unset upstream_name
+	unset upstream
+	root_flag="--root"
+	upstream_arg="$root_flag"
+fi
 
 # Make sure the branch to rebase onto is valid.
 onto_name=${newbase-"$upstream_name"}
 onto=$(git rev-parse --verify "${onto_name}^0") || exit
 
 # If a hook exists, give it a chance to interrupt
-run_pre_rebase_hook ${1+"$@"}
+run_pre_rebase_hook "$upstream_arg" "$@"
 
 # If the branch to rebase is given, that is the branch we will rebase
 # $branch_name -- branch being rebased, or HEAD (already detached)
@@ -362,16 +377,16 @@ run_pre_rebase_hook ${1+"$@"}
 # $head_name -- refs/heads/<that-branch> or "detached HEAD"
 switch_to=
 case "$#" in
-2)
+1)
 	# Is it "rebase other $branchname" or "rebase other $commit"?
-	branch_name="$2"
-	switch_to="$2"
+	branch_name="$1"
+	switch_to="$1"
 
-	if git show-ref --verify --quiet -- "refs/heads/$2" &&
-	   branch=$(git rev-parse -q --verify "refs/heads/$2")
+	if git show-ref --verify --quiet -- "refs/heads/$1" &&
+	   branch=$(git rev-parse -q --verify "refs/heads/$1")
 	then
-		head_name="refs/heads/$2"
-	elif branch=$(git rev-parse -q --verify "$2")
+		head_name="refs/heads/$1"
+	elif branch=$(git rev-parse -q --verify "$1")
 	then
 		head_name="detached HEAD"
 	else
@@ -393,7 +408,8 @@ case "$#" in
 esac
 orig_head=$branch
 
-# Now we are rebasing commits $upstream..$branch on top of $onto
+# Now we are rebasing commits $upstream..$branch (or with --root,
+# everything leading up to $branch) on top of $onto
 
 # Check if we are already based on $onto with linear history,
 # but this should be done only when upstream and onto are the same.
@@ -429,10 +445,16 @@ then
 	exit 0
 fi
 
+if test ! -z "$rebase_root"; then
+	revisions="$onto..$orig_head"
+else
+	revisions="$upstream..$orig_head"
+fi
+
 if test -z "$do_merge"
 then
 	git format-patch -k --stdout --full-index --ignore-if-in-upstream \
-		"$upstream..$orig_head" |
+		$root_flag "$revisions" |
 	git am $git_am_opt --rebasing --resolvemsg="$RESOLVEMSG" &&
 	move_to_original_branch
 	ret=$?
@@ -455,7 +477,7 @@ echo "$orig_head" > "$dotest/orig-head"
 echo "$head_name" > "$dotest/head-name"
 
 msgnum=0
-for cmt in `git rev-list --reverse --no-merges "$upstream..$orig_head"`
+for cmt in `git rev-list --reverse --no-merges "$revisions"`
 do
 	msgnum=$(($msgnum + 1))
 	echo "$cmt" > "$dotest/cmt.$msgnum"
diff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh
new file mode 100755
index 0000000..1978512
--- /dev/null
+++ b/t/t3412-rebase-root.sh
@@ -0,0 +1,86 @@
+#!/bin/sh
+
+test_description='git rebase --root
+
+Tests if git rebase --root --onto <newparent> can rebase the root commit.
+'
+. ./test-lib.sh
+
+test_expect_success 'prepare repository' '
+	echo 1 > A &&
+	git add A &&
+	git commit -m 1 &&
+	echo 2 > A &&
+	git add A &&
+	git commit -m 2 &&
+	git symbolic-ref HEAD refs/heads/other &&
+	rm .git/index &&
+	echo 1 > A &&
+	git add A &&
+	git commit -m 1b &&
+	echo 3 > B &&
+	git add B &&
+	git commit -m 3 &&
+	echo 4 > B &&
+	git add B &&
+	git commit -m 4
+'
+
+test_expect_success 'rebase --root expects --onto' '
+	test_must_fail git rebase --root
+'
+
+test_expect_success 'setup pre-rebase hook' '
+	mkdir -p .git/hooks &&
+	cat >.git/hooks/pre-rebase <<EOF &&
+#!$SHELL_PATH
+echo "\$1,\$2" >.git/PRE-REBASE-INPUT
+EOF
+	chmod +x .git/hooks/pre-rebase
+'
+cat > expect <<EOF
+4
+3
+2
+1
+EOF
+
+test_expect_success 'rebase --root --onto <newbase>' '
+	git checkout -b work &&
+	git rebase --root --onto master &&
+	git log --pretty=tformat:"%s" > rebased &&
+	test_cmp expect rebased
+'
+
+test_expect_success 'pre-rebase got correct input (1)' '
+	test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,
+'
+
+test_expect_success 'rebase --root --onto <newbase> <branch>' '
+	git branch work2 other &&
+	git rebase --root --onto master work2 &&
+	git log --pretty=tformat:"%s" > rebased2 &&
+	test_cmp expect rebased2
+'
+
+test_expect_success 'pre-rebase got correct input (2)' '
+	test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,work2
+'
+
+test_expect_success 'setup pre-rebase hook that fails' '
+	mkdir -p .git/hooks &&
+	cat >.git/hooks/pre-rebase <<EOF &&
+#!$SHELL_PATH
+false
+EOF
+	chmod +x .git/hooks/pre-rebase
+'
+
+test_expect_success 'pre-rebase hook stops rebase' '
+	git checkout -b stops1 other &&
+	GIT_EDITOR=: test_must_fail git rebase --root --onto master &&
+	test "z$(git symbolic-ref HEAD)" = zrefs/heads/stops1
+	test 0 = $(git rev-list other...stops1 | wc -l)
+'
+
+test_done
-- 
tg: (cb706e1..) t/rr-normal (depends on: origin/master t/rebase-hook-order)

^ permalink raw reply related

* Re: how to track the history of a line in a file
From: david @ 2009-01-03  0:59 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, git
In-Reply-To: <7vvdsxb9oh.fsf@gitster.siamese.dyndns.org>

On Fri, 2 Jan 2009, Junio C Hamano wrote:

> david@lang.hm writes:
>
>> I was misunderstanding git blame
>
> You may find the --porcelain output format of git-blame useful to make
> your script safer and more robust.

where is this output defined? I can look at it and understand it, but I 
don't know what is guarenteeded to exist, what will be on a specific line, 
and what may vanish on me.

David Lang

^ permalink raw reply

* Re: how to track the history of a line in a file
From: Thomas Rast @ 2009-01-03  0:07 UTC (permalink / raw)
  To: david; +Cc: Junio C Hamano, Jeff King, git
In-Reply-To: <alpine.DEB.1.10.0901021658330.21567@asgard.lang.hm>

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

david@lang.hm wrote:
> On Fri, 2 Jan 2009, Junio C Hamano wrote:
> > You may find the --porcelain output format of git-blame useful to make
> > your script safer and more robust.
> 
> where is this output defined? I can look at it and understand it, but I 
> don't know what is guarenteeded to exist, what will be on a specific line, 
> and what may vanish on me.

man git-blame | less -p PORCELAIN\ FORMAT

-- 
Thomas Rast
trast@{inf,student}.ethz.ch


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* git-fast-export bundle doc
From: jidanni @ 2009-01-03  0:52 UTC (permalink / raw)
  To: git

Please improve git-fast-export.txt. It says

       This program dumps the given revisions in a form suitable to be
       piped into git-fast-import.

<revlist> isn't mentioned in the SYNOPSIS.
And there is no hyperlink to the git-fast-import man page, nor in SEE ALSO.)

       You can use it as a human readable bundle replacement (see
       git-bundle(1))

But I tried it and there are apparently a few steps not mentioned that
are needed after git-fast-import before you can actually see the files
again on the other side of the sneakernet.

I used --all, which is in EXAMPLES but not OPTIONS.

Else nothing happens and no error is caught:
$ git fast-export
$

Also the git-bundle man page should SEE ALSO git-fast-export and maybe
even git-fast-import, which itself makes no mention of git-fast-export.

^ 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