* Re: More help needed on merging unrelated repos
From: Andreas Ericsson @ 2008-11-04 22:04 UTC (permalink / raw)
To: Christian MICHON; +Cc: Git Mailing List
In-Reply-To: <46d6db660811041308o19f1131dm4d49b6703fa6d22b@mail.gmail.com>
Christian MICHON wrote:
> Andreas Ericsson wrote:
>> Christian MICHON wrote:
>>> Hi,
>>>
>>> I previously posted here a question on how to merge unrelated repos,
>>> and I was quite happy with the answer.
>>> git pull repo_name repo_branch
>>>
>>> Yet, when I merge these repos (they're unrelated), I'd like to merge
>>> all of them at once.
>>>
>>> How do I pull for example 2 repos in 1 command ? I cannot figure out
>>> the exact syntax to use.
>>>
>>> I tried:
>>> git pull ../i1 0.5 ../i2 master
>>> git pull ../i1 0.5 -- ../i2 master
>>>
>>> I also tried to play with --no-commit and -s to no avail.
>>>
>>> Does anyone of you already use this and knows the trick ? Thanks in
>>> advance!
>>>
>> You can only pull from a single repository at a time. The first way of doing
>> what you want that comes to mind is:
>>
>> git remote add lib1 lib1url
>> git remote add lib2 lib2url
>> git fetch lib1 && git fetch lib2 && git merge lib1/master lib2/master
>>
>> --
>> Andreas Ericsson andreas.ericsson@op5.se
>> OP5 AB www.op5.se
>> Tel: +46 8-230225 Fax: +46 8-230231
>>
>
> and apparently this strategy (which I tried before too :( ) fails when merging.
>
> example:
> repo i1 contains file 'a'
> repo i2 contains file 'b'
> new repo z contains file 'readme' and I want to pull repo i1 and i2 at
> the same time inside repo z.
>
> typically, I've to pull 1 repo at a time, if I use pull. If I fetch
> both without merge, and then I try a merge, it fails.
> maybe I'm on a wild goose chase after all.
>
Ah, right. Octopus merge always does merge head reduction, but to do
that it needs to find a common ancestor. When no such ancestor exists,
it will fail (with a message like "shouldn't be doing octopus merge"?).
If there's no "--no-reduce-heads" option to "git merge", I think you're
screwed with getting that to happen in a single commit.
Oh wait.
git merge i1 && git merge --no-commit i2 && git commit --amend
might work. I'm still shooting from the hip though, and now it's far too
late for me to think more. gl though.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: [PATCH 4/4] Add support for 'namespace' history simplification
From: Clemens Buchacher @ 2008-11-04 21:33 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Brian Foster, Junio C Hamano, Git Mailing List
In-Reply-To: <alpine.LFD.2.00.0811031139520.3419@nehalem.linux-foundation.org>
On Mon, Nov 03, 2008 at 11:43:00AM -0800, Linus Torvalds wrote:
> gitk --simplify-namespace
Very nice. git log --graph seems to give slightly different results though.
In particular, in git.git if I do
git for-each-ref --format="%(refname)" refs/remotes/origin | \
xargs git log --simplify-namespace --graph --pretty='format:%H%n' | \
git name-rev --stdin --name-only | \
less
some of the history is not connected. Is this a known limitation of
git log --graph?
^ permalink raw reply
* Re: More help needed on merging unrelated repos
From: Christian MICHON @ 2008-11-04 21:08 UTC (permalink / raw)
To: Andreas Ericsson; +Cc: Git Mailing List
In-Reply-To: <4910ACCA.7080007@op5.se>
Andreas Ericsson wrote:
> Christian MICHON wrote:
>>
>> Hi,
>>
>> I previously posted here a question on how to merge unrelated repos,
>> and I was quite happy with the answer.
>> git pull repo_name repo_branch
>>
>> Yet, when I merge these repos (they're unrelated), I'd like to merge
>> all of them at once.
>>
>> How do I pull for example 2 repos in 1 command ? I cannot figure out
>> the exact syntax to use.
>>
>> I tried:
>> git pull ../i1 0.5 ../i2 master
>> git pull ../i1 0.5 -- ../i2 master
>>
>> I also tried to play with --no-commit and -s to no avail.
>>
>> Does anyone of you already use this and knows the trick ? Thanks in
>> advance!
>>
>
> You can only pull from a single repository at a time. The first way of doing
> what you want that comes to mind is:
>
> git remote add lib1 lib1url
> git remote add lib2 lib2url
> git fetch lib1 && git fetch lib2 && git merge lib1/master lib2/master
>
> --
> Andreas Ericsson andreas.ericsson@op5.se
> OP5 AB www.op5.se
> Tel: +46 8-230225 Fax: +46 8-230231
>
and apparently this strategy (which I tried before too :( ) fails when merging.
example:
repo i1 contains file 'a'
repo i2 contains file 'b'
new repo z contains file 'readme' and I want to pull repo i1 and i2 at
the same time inside repo z.
typically, I've to pull 1 repo at a time, if I use pull. If I fetch
both without merge, and then I try a merge, it fails.
maybe I'm on a wild goose chase after all.
thanks
--
Christian
--
http://detaolb.sourceforge.net/, a linux distribution for Qemu with Git inside !
^ permalink raw reply
* [PATCH v2] push: fix local refs update if already up-to-date
From: Clemens Buchacher @ 2008-11-04 20:57 UTC (permalink / raw)
To: Jeff King, Junio C Hamano; +Cc: git
In-Reply-To: <20081104042643.GA31276@coredump.intra.peff.net>
git push normally updates local refs only after a successful push. If the
remote already has the updates -- pushed indirectly through another repository,
for example -- we forget to update local tracking refs.
Signed-off-by: Clemens Buchacher <drizzd@aon.at>
---
On Mon, Nov 03, 2008 at 11:26:44PM -0500, Jeff King wrote:
> Nit: Just reading the test, it is hard to see what is interesting about
> it (though obviously I can blame it back to your commit :) ). Maybe a
> more descriptive title like 'push updates uptodate local refs' would
> make sense.
That is all I changed in this update. Pending an Ack/Nack from Jeff I feel
that I'm done.
builtin-send-pack.c | 11 +++++------
t/t5516-fetch-push.sh | 18 ++++++++++++++++++
2 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/builtin-send-pack.c b/builtin-send-pack.c
index d68ce2d..c91c12f 100644
--- a/builtin-send-pack.c
+++ b/builtin-send-pack.c
@@ -230,7 +230,7 @@ static void update_tracking_ref(struct remote *remote, struct ref *ref)
{
struct refspec rs;
- if (ref->status != REF_STATUS_OK)
+ if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
return;
rs.src = ref->name;
@@ -444,15 +444,15 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
}
else
new_sha1 = ref->peer_ref->new_sha1;
+ hashcpy(ref->new_sha1, new_sha1);
-
- ref->deletion = is_null_sha1(new_sha1);
+ ref->deletion = is_null_sha1(ref->new_sha1);
if (ref->deletion && !allow_deleting_refs) {
ref->status = REF_STATUS_REJECT_NODELETE;
continue;
}
if (!ref->deletion &&
- !hashcmp(ref->old_sha1, new_sha1)) {
+ !hashcmp(ref->old_sha1, ref->new_sha1)) {
ref->status = REF_STATUS_UPTODATE;
continue;
}
@@ -480,14 +480,13 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
!ref->deletion &&
!is_null_sha1(ref->old_sha1) &&
(!has_sha1_file(ref->old_sha1)
- || !ref_newer(new_sha1, ref->old_sha1));
+ || !ref_newer(ref->new_sha1, ref->old_sha1));
if (ref->nonfastforward && !ref->force && !args.force_update) {
ref->status = REF_STATUS_REJECT_NONFASTFORWARD;
continue;
}
- hashcpy(ref->new_sha1, new_sha1);
if (!ref->deletion)
new_refs++;
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index f0030ad..a82ce5a 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -437,6 +437,24 @@ test_expect_success 'push updates local refs' '
'
+test_expect_success 'push updates up-to-date local refs' '
+
+ rm -rf parent child &&
+ mkdir parent &&
+ (cd parent && git init &&
+ echo one >foo && git add foo && git commit -m one) &&
+ git clone parent child1 &&
+ git clone parent child2 &&
+ (cd child1 &&
+ echo two >foo && git commit -a -m two &&
+ git push) &&
+ (cd child2 &&
+ git pull ../child1 master &&
+ git push &&
+ test $(git rev-parse master) = $(git rev-parse remotes/origin/master))
+
+'
+
test_expect_success 'push does not update local refs on failure' '
rm -rf parent child &&
--
1.6.0.3.617.ge4eb0
^ permalink raw reply related
* Re: [PATCH v2 1/3] t7700: demonstrate mishandling of objects in packs with a .keep file
From: Andreas Ericsson @ 2008-11-04 20:21 UTC (permalink / raw)
To: Brandon Casey
Cc: Junio C Hamano, Shawn O. Pearce, Git Mailing List, Nicolas Pitre
In-Reply-To: <V78jOMhdYwpSlLU-YzsqEHZxJyrvKbXRQbKsuNPZOEtB8E0kZ5Wi7Q@cipher.nrlssc.navy.mil>
Brandon Casey wrote:
> Andreas Ericsson wrote:
>> Brandon Casey wrote:
>>> From: Brandon Casey <drafnel@gmail.com>
>>>
>>> Objects residing in pack files that have an associated .keep file are not
>>> supposed to be repacked into new pack files, but they are.
>>>
>>> Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
>>> ---
>>>
>>>
>>> This version replaces the use of 'head -n -1' with a grep, and should
>>> work on
>>> all platforms.
>>>
>> sed 1q is faster, as it stops parsing after the first line (the same as
>> 'head
>> -n 1' does, but in a more portable fashion).
>
> Except that I wanted all but the _last_ line though.
>
Ach pooie. That's what I get for trying to review stuff while watching
old 70's samurai movies. I misread your 'head' command.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: More help needed on merging unrelated repos
From: Andreas Ericsson @ 2008-11-04 20:12 UTC (permalink / raw)
To: Christian MICHON; +Cc: Git Mailing List
In-Reply-To: <46d6db660811040514qc6c9663u17bd231e1ba662ad@mail.gmail.com>
Christian MICHON wrote:
> Hi,
>
> I previously posted here a question on how to merge unrelated repos,
> and I was quite happy with the answer.
> git pull repo_name repo_branch
>
> Yet, when I merge these repos (they're unrelated), I'd like to merge
> all of them at once.
>
> How do I pull for example 2 repos in 1 command ? I cannot figure out
> the exact syntax to use.
>
> I tried:
> git pull ../i1 0.5 ../i2 master
> git pull ../i1 0.5 -- ../i2 master
>
> I also tried to play with --no-commit and -s to no avail.
>
> Does anyone of you already use this and knows the trick ? Thanks in advance!
>
You can only pull from a single repository at a time. The first way of doing
what you want that comes to mind is:
git remote add lib1 lib1url
git remote add lib2 lib2url
git fetch lib1 && git fetch lib2 && git merge lib1/master lib2/master
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: [PATCH 4/5] git send-email: ask less questions when --compose is used.
From: Francis Galiegue @ 2008-11-04 20:09 UTC (permalink / raw)
To: Pierre Habouzit; +Cc: git
In-Reply-To: <1225815858-30617-5-git-send-email-madcoder@debian.org>
Le Tuesday 04 November 2008 17:24:17, vous avez écrit :
> + if ($summary_empty) {
> + print "Summary email is empty, --> skpping <-- it\n";
>
Typo...
--
fge
^ permalink raw reply
* Re: [PATCH v2 1/3] t7700: demonstrate mishandling of objects in packs with a .keep file
From: Brandon Casey @ 2008-11-04 20:01 UTC (permalink / raw)
To: Junio C Hamano
Cc: Andreas Ericsson, Shawn O. Pearce, Git Mailing List,
Nicolas Pitre
In-Reply-To: <7vmygfqn92.fsf@gitster.siamese.dyndns.org>
Junio C Hamano wrote:
> Brandon Casey <casey@nrlssc.navy.mil> writes:
>> sed -n -e '$q' -e 'p'
>
> You surely meant "sed -e '$d'", right?
Your sed-fu is quite impressive.
-b
^ permalink raw reply
* Re: [PATCH v2 1/3] t7700: demonstrate mishandling of objects in packs with a .keep file
From: Junio C Hamano @ 2008-11-04 19:55 UTC (permalink / raw)
To: Brandon Casey
Cc: Andreas Ericsson, Shawn O. Pearce, Git Mailing List,
Nicolas Pitre
In-Reply-To: <V78jOMhdYwpSlLU-YzsqEHZxJyrvKbXRQbKsuNPZOEtB8E0kZ5Wi7Q@cipher.nrlssc.navy.mil>
Brandon Casey <casey@nrlssc.navy.mil> writes:
> Andreas Ericsson wrote:
>
>> sed 1q is faster, as it stops parsing after the first line (the same as
>> 'head
>> -n 1' does, but in a more portable fashion).
If your sed is GNU, and you are doing this for a small file, the startup
cost of it may dwarf such gain ;-)
> Except that I wanted all but the _last_ line though.
>
> I didn't think about using sed. Perhaps I could have used something like
>
> sed -n -e '$q' -e 'p'
You surely meant "sed -e '$d'", right?
> The grep works though.
Indeed.
^ permalink raw reply
* Re: [PATCH v2 1/3] t7700: demonstrate mishandling of objects in packs with a .keep file
From: Brandon Casey @ 2008-11-04 19:49 UTC (permalink / raw)
To: Andreas Ericsson
Cc: Junio C Hamano, Shawn O. Pearce, Git Mailing List, Nicolas Pitre
In-Reply-To: <49109FD4.30003@op5.se>
Andreas Ericsson wrote:
> Brandon Casey wrote:
>> From: Brandon Casey <drafnel@gmail.com>
>>
>> Objects residing in pack files that have an associated .keep file are not
>> supposed to be repacked into new pack files, but they are.
>>
>> Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
>> ---
>>
>>
>> This version replaces the use of 'head -n -1' with a grep, and should
>> work on
>> all platforms.
>>
>
> sed 1q is faster, as it stops parsing after the first line (the same as
> 'head
> -n 1' does, but in a more portable fashion).
Except that I wanted all but the _last_ line though.
I didn't think about using sed. Perhaps I could have used something like
sed -n -e '$q' -e 'p'
The grep works though.
-brandon
^ permalink raw reply
* Re: [PATCH] Documentation: add a planning document for the next CLI revamp
From: Junio C Hamano @ 2008-11-04 19:46 UTC (permalink / raw)
To: Sam Vilain
Cc: Dmitry Potapov, Jeff King, Sam Vilain, git, Johannes Schindelin,
Scott Chacon, Tom Preston-Werner, J.H., Christian Couder,
Kai Blin
In-Reply-To: <1225822231.6722.3.camel@maia.lan>
Sam Vilain <sam@vilain.net> writes:
> On Tue, 2008-11-04 at 12:18 +0300, Dmitry Potapov wrote:
> ...
>> The only one who does publishing to the official repository
>> is the maintainer, and the maintainer is most likely to run some tests
>> after merging all changes, which takes some time. So, it is rarely push
>> the current branch, it is usually the branch that has been tested, so
>> the name of the branch should be specified explicitly anyway.
>
> Why is that relevant? That person can still use the explicit version of
> the command.
Back when "git push $there :" were not available, the default matching
behaviour was the _only_ way to say "I know the set of branches I want to
publish, and I have many more private branches in my primary work
repository. I do not want to list the set of branches to publish every
time when I type 'git push', nor I want to configure it --- Heck, I
shouldn't have to list them, the public repository I am pushing to already
has that list, and it is the set of branches that exist there".
These days, people who would want the maching behaviour can explicitly ask
for it, so there is one less reason to resist changing the default
(i.e. earlier explicitly askinf for "matching" was impossible, but now we
can). The remaining reason of resistance is pure inertia (i.e. not
changing the behaviour of the command only because you upgraded your git),
and the only way to address it is to start issuing the warning when "git
push" or "git push $there" is used and the matching behaviour was chosen
without configuration (i.e. no "remote.<there>.push = :"), and keep it
that way for two release cycles, and finally change the default.
^ permalink raw reply
* Re: [PATCH] t7700: demonstrate mishandling of objects in packs with a .keep file
From: Andreas Ericsson @ 2008-11-04 19:25 UTC (permalink / raw)
To: Brandon Casey; +Cc: drafnel, git, gitster, nico
In-Reply-To: <76IhmMdjmr4jA4xApPpvlZ4vfjtqEDsUaFal2mN5MHfI0MChFmsj5g@cipher.nrlssc.navy.mil>
Brandon Casey wrote:
> Andreas Ericsson wrote:
>
>> So long as "git repack -a" still creates a mega-pack, I'm fine with
>> whatever.
>
> I don't think it will after pack-objects is taught about .keep files, and
In that case you're almost certainly breaking something.
> I don't think it will _now_ if all of your packs have .keep files.
>
It should, by copying the objects from the .keep-marked packfiles. Otherwise
either repack or the repack docs are in error.
> 'repack -a' will call pack-objects with either '--unpack=<packfile>' for
> each pack file without a .keep file, or with '--unpacked --incremental' if
> there are no pack files without .keep files.
>
> In the first case, the modifications to pack-objects that I propose
> will prevent objects that exist in local packs with .keep files
> from being packed into the new pack.
>
> In the second case, the --incremental option would have done the same thing.
>
> So this inconsistency already existed, but will now be removed in favor of
> honoring .keep files.
>
That means the nifty hack of incrementally and sometimes fully repack the
odb to speed up cloning over dumb protocols no longer works properly, then.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: [PATCH v2 1/3] t7700: demonstrate mishandling of objects in packs with a .keep file
From: Andreas Ericsson @ 2008-11-04 19:17 UTC (permalink / raw)
To: Brandon Casey
Cc: Junio C Hamano, Shawn O. Pearce, Git Mailing List, Nicolas Pitre
In-Reply-To: <muOuA1nLBoljLnZoguxeFeKt-8Q-I9Y3ljvxnLWLt9KyA8HwVtMa4Q@cipher.nrlssc.navy.mil>
Brandon Casey wrote:
> From: Brandon Casey <drafnel@gmail.com>
>
> Objects residing in pack files that have an associated .keep file are not
> supposed to be repacked into new pack files, but they are.
>
> Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
> ---
>
>
> This version replaces the use of 'head -n -1' with a grep, and should work on
> all platforms.
>
sed 1q is faster, as it stops parsing after the first line (the same as 'head
-n 1' does, but in a more portable fashion).
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: [PATCH] Documentation: add a planning document for the next CLI revamp
From: Sam Vilain @ 2008-11-04 18:10 UTC (permalink / raw)
To: Dmitry Potapov
Cc: Junio C Hamano, Jeff King, Sam Vilain, git, Johannes Schindelin,
Scott Chacon, Tom Preston-Werner, J.H., Christian Couder,
Kai Blin
In-Reply-To: <20081104091800.GB24100@dpotapov.dyndns.org>
On Tue, 2008-11-04 at 12:18 +0300, Dmitry Potapov wrote:
> > I can see that some people want this behaviour by default; but to me
> > "push the current branch back to where it came from" seems like far more
> > a rational default for at least 90% of users.
>
> I think it depends on one's workflow. If you use a centralized workflow
> as with CVS then yes, 90% cases you want to push the current branch. On
> the other hand, if people push their changes to the server only for
> review, it means that accidentally pushing more than one intended is not
> a big deal.
Perhaps not, but it was still unintended. I really can't understand the
opposition to making this command make many people less angry at it.
> The only one who does publishing to the official repository
> is the maintainer, and the maintainer is most likely to run some tests
> after merging all changes, which takes some time. So, it is rarely push
> the current branch, it is usually the branch that has been tested, so
> the name of the branch should be specified explicitly anyway.
Why is that relevant? That person can still use the explicit version of
the command.
Sam.
^ permalink raw reply
* [PATCH 3/3 v2] Documentation: add "git bisect replace" documentation
From: Christian Couder @ 2008-11-04 17:35 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
Documentation/git-bisect.txt | 63 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 63 insertions(+), 0 deletions(-)
diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt
index c7981ef..3cb98b9 100644
--- a/Documentation/git-bisect.txt
+++ b/Documentation/git-bisect.txt
@@ -24,6 +24,7 @@ on the subcommand:
git bisect visualize
git bisect replay <logfile>
git bisect log
+ git bisect replace <rev> [<rev>]
git bisect run <cmd>...
This command uses 'git-rev-list --bisect' to help drive the
@@ -186,6 +187,68 @@ $ git bisect start v2.6.20-rc6 v2.6.20-rc4 v2.6.20-rc1 --
# v2.6.20-rc4 and v2.6.20-rc1 are good
------------
+Bisect replace
+~~~~~~~~~~~~~~
+
+This subcommand should be used when you have a branch or a part of a
+branch that isn't easily bisectable because of a bug that has been
+fixed latter.
+
+We suppose that a bug as been introduced at some point, say A, and
+that it has been fixed latter at another point, say B, but that
+between these points the code is not easily testable because of the
+bug, so it's not easy to bisect between these points.
+
+In this case you can create a branch starting at the parent of A, say
+O, that has a fixed history. In this fixed history for example, there
+could be first a commit C that is the result of squashing A and B
+together and then all the commits between A and B that have been cherry
+picked.
+
+For example, let's say the commits between A and B are X1, X2, ... Xn
+and they have been cherry picked after C as Y1, Y2, ... Yn:
+
+------------
+ C--Y1--Y2--...--Yn
+ /
+...--O--A--X1--X2--...--Xn--B--...
+------------
+
+By design, the last cherry picked commit (Yn) should point to the same
+tree as commit B.
+
+So in this case you can say:
+
+------------
+$ git bisect replace B Yn
+------------
+
+and commit B will be tagged with a special name like:
+"bisect-replace-with-Yn"
+
+(A branch that points to commit Yn will also be created with a name
+like: "bisect-replace-B")
+
+When bisecting, each commit with one of those tags will be grafted so
+that its parents will be replaced by the commit specified in the tag.
+
+In the example above, that means that instead of the above graph, the
+following graph will be bisected:
+
+------------
+ C--Y1--Y2--...--Yn
+ / \
+...--O B--...
+------------
+
+This means that the bisections on this branch may be much easier
+because the bug introduced by commit A and fixed by commit B will not
+annoy you anymore.
+
+As the branches and tags created by "git bisect replace" can be shared
+between developers, this feature might be especially usefull on big
+projects where many people often bisect the same code base.
+
Bisect run
~~~~~~~~~~
--
1.6.0.3.528.gad674
^ permalink raw reply related
* [PATCH 2/3 v2] bisect: add test cases for "git bisect replace"
From: Christian Couder @ 2008-11-04 17:35 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
t/t6035-bisect-replace.sh | 114 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 114 insertions(+), 0 deletions(-)
create mode 100755 t/t6035-bisect-replace.sh
diff --git a/t/t6035-bisect-replace.sh b/t/t6035-bisect-replace.sh
new file mode 100755
index 0000000..e07cc10
--- /dev/null
+++ b/t/t6035-bisect-replace.sh
@@ -0,0 +1,114 @@
+#!/bin/sh
+#
+# Copyright (c) 2008 Christian Couder
+#
+test_description='Test git bisect replace functionality'
+
+exec </dev/null
+
+. ./test-lib.sh
+
+add_and_commit_file()
+{
+ _file="$1"
+ _msg="$2"
+
+ git add $_file || return $?
+ test_tick || return $?
+ git commit --quiet -m "$_file: $_msg"
+}
+
+HASH1=
+HASH2=
+HASH3=
+HASH4=
+HASH5=
+HASH6=
+
+test_expect_success 'set up buggy branch' '
+ echo "line 1" >> hello &&
+ echo "line 2" >> hello &&
+ echo "line 3" >> hello &&
+ echo "line 4" >> hello &&
+ add_and_commit_file hello "4 lines" &&
+ HASH1=$(git rev-parse --verify HEAD) &&
+ echo "line BUG" >> hello &&
+ echo "line 6" >> hello &&
+ echo "line 7" >> hello &&
+ echo "line 8" >> hello &&
+ add_and_commit_file hello "4 more lines with a BUG" &&
+ HASH2=$(git rev-parse --verify HEAD) &&
+ echo "line 9" >> hello &&
+ echo "line 10" >> hello &&
+ add_and_commit_file hello "2 more lines" &&
+ HASH3=$(git rev-parse --verify HEAD) &&
+ echo "line 11" >> hello &&
+ add_and_commit_file hello "1 more line" &&
+ HASH4=$(git rev-parse --verify HEAD) &&
+ sed -e "s/BUG/5/" hello > hello.new &&
+ mv hello.new hello &&
+ add_and_commit_file hello "BUG fixed" &&
+ HASH5=$(git rev-parse --verify HEAD) &&
+ echo "line 12" >> hello &&
+ echo "line 13" >> hello &&
+ add_and_commit_file hello "2 more lines" &&
+ HASH6=$(git rev-parse --verify HEAD)
+'
+
+HASHFIX2=
+HASHFIX3=
+HASHFIX4=
+
+test_expect_success 'set up fixed branch' '
+ git checkout $HASH1 &&
+ echo "line 5" >> hello &&
+ echo "line 6" >> hello &&
+ echo "line 7" >> hello &&
+ echo "line 8" >> hello &&
+ add_and_commit_file hello "4 more lines with no BUG" &&
+ HASHFIX2=$(git rev-parse --verify HEAD) &&
+ git cherry-pick $HASH3 &&
+ HASHFIX3=$(git rev-parse --verify HEAD) &&
+ git cherry-pick $HASH4 &&
+ HASHFIX4=$(git rev-parse --verify HEAD)
+'
+
+test_expect_success '"git bisect replace" buggy branch with fixed one' '
+ git bisect replace $HASH5 HEAD
+'
+
+test_expect_success 'replace works when bisecting with a later bad commit' '
+ git rev-list --bisect-all $HASH6 > rev_list.txt &&
+ grep $HASHFIX2 rev_list.txt &&
+ grep $HASHFIX3 rev_list.txt &&
+ grep $HASHFIX4 rev_list.txt &&
+ test_must_fail grep $HASH2 rev_list.txt &&
+ test_must_fail grep $HASH3 rev_list.txt &&
+ test_must_fail grep $HASH4 rev_list.txt
+'
+
+test_expect_success 'replace works starting from replaced commit' '
+ git rev-list --bisect-all $HASH5 > rev_list.txt &&
+ grep $HASHFIX2 rev_list.txt &&
+ grep $HASHFIX3 rev_list.txt &&
+ grep $HASHFIX4 rev_list.txt &&
+ test_must_fail grep $HASH2 rev_list.txt &&
+ test_must_fail grep $HASH3 rev_list.txt &&
+ test_must_fail grep $HASH4 rev_list.txt
+'
+
+test_expect_success 'standard bisect works' '
+ git bisect start $HASH6 $HASH1 &&
+ test "$(git rev-parse --verify HEAD)" = "$HASHFIX3" &&
+ git bisect good &&
+ test "$(git rev-parse --verify HEAD)" = "$HASH5" &&
+ git bisect bad &&
+ test "$(git rev-parse --verify HEAD)" = "$HASHFIX4" &&
+ git bisect bad > my_bisect_log.txt &&
+ grep "$HASHFIX4 is first bad commit" my_bisect_log.txt &&
+ git bisect reset
+'
+
+#
+#
+test_done
--
1.6.0.3.528.gad674
^ permalink raw reply related
* [PATCH 1/3 v2] bisect: add "git bisect replace" subcommand
From: Christian Couder @ 2008-11-04 17:35 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
This subcommand should be used when you have a branch or a part of a
branch that isn't easily bisectable because of a bug that has been
fixed latter.
We suppose that a bug as been introduced at some point, say A, and
that it has been fixed latter at another point, say B, but that
between these points the code is not easily testable because of the
bug, so it's not easy to bisect between these points.
In this case you can create a branch starting at the parent of A, say
O, that has a fixed history. In this fixed history for example, there
could be first a commit C that is the result of squashing A and B
together and then all the commits between A and B that have been
cherry picked.
For example, let's say the commits between A and B are X1, X2, ... Xn
and they have been cherry picked after C as Y1, Y2, ... Yn:
C--Y1--Y2--...--Yn
/
...--O--A--X1--X2--...--Xn--B--...
By design, the last cherry picked commit (Yn) should point to the same
tree as commit B.
So in this case you can say:
$ git bisect replace B Yn
and commit B will be tagged with a special name like:
"bisect-replace-with-Yn"
(A branch that points to commit Yn will also be created with a name
like: "bisect-replace-B")
When bisecting, each commit with one of those tags will be grafted so
that its parents will be replaced by the commit specified in the tag.
In the example above that means that instead of the above graph, the
following graph will be bisected:
C--Y1--Y2--...--Yn
/ \
...--O B--...
This means that the bisections on this branch will be much easier
because the bug introduced by commit A and fixed by commit B will not
annoy you anymore.
As the branches and tags created by "git bisect replace" can be shared
between developers, this feature might be especially usefull on big
projects where many people often bisect the same code base.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin-rev-list.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++-
git-bisect.sh | 40 +++++++++++++++++++++++-
2 files changed, 125 insertions(+), 2 deletions(-)
Changes since previous series are the following:
- replace parents of a commit that has already been created
when bisect_replace() is called (1/1)
- check that the new parent of a commit exists before using it
to replace existing parents (1/1)
- improve tests (2/3)
- add a documentation patch (3/3)
Thank you Junio for your help in designing this during the GitTogether,
especially for the trick to change the parents of the commit fixing the
bug.
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 06cdeb7..f29c548 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -529,6 +529,88 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
return best_bisection_sorted(list, nr);
}
+static struct commit *check_replace_parents(unsigned char *parent,
+ const char *refname,
+ const unsigned char *sha1)
+{
+ struct commit *new_parent;
+ if (get_sha1_hex(refname + 20, parent)) {
+ warning("bad sha1 in tag name '%s'", refname);
+ return NULL;
+ }
+ new_parent = lookup_commit(parent);
+ if (!new_parent) {
+ warning("tag name '%s' refers to an unknown commit\n"
+ "Please make sure you have the branch "
+ "'bisect-replace-%s'.\n"
+ "Or delete tag '%s'.",
+ refname, sha1_to_hex(sha1), refname);
+ return NULL;
+ }
+ return new_parent;
+}
+
+static void replace_parents(struct commit *commit,
+ const char *refname,
+ const unsigned char *sha1)
+{
+ unsigned char parent[20];
+ struct commit *new_parent;
+
+ new_parent = check_replace_parents(parent, refname, sha1);
+
+ if (new_parent) {
+ free_commit_list(commit->parents);
+ commit->parents = NULL;
+ commit_list_insert(new_parent, &commit->parents);
+ }
+}
+
+static int bisect_replace(const char *refname, const unsigned char *sha1,
+ int flag, void *cb_data)
+{
+ struct object *obj;
+ struct commit_graft *graft;
+ struct commit *new_parent;
+
+ if (prefixcmp(refname, "bisect-replace-with-"))
+ return 0;
+
+ /* See if we already have the commit */
+
+ obj = lookup_object(sha1);
+ if (obj) {
+ struct commit *commit;
+ if (obj->type != OBJ_COMMIT)
+ return 0;
+ commit = (struct commit *) obj;
+ if (commit->object.parsed) {
+ replace_parents(commit, refname, sha1);
+ return 0;
+ }
+ }
+
+ /* Create a graft to replace current commit */
+
+ graft = xmalloc(sizeof(*graft) + 20);
+
+ hashcpy(graft->sha1, sha1);
+ graft->nr_parent = 1;
+
+ /*
+ * We create commits that we may not need
+ * and cannot easily free, but at least it is safe.
+ */
+ new_parent = check_replace_parents(graft->parent[0], refname, sha1);
+
+ if (new_parent)
+ register_commit_graft(graft, 1);
+ else
+ free(graft);
+
+ return 0;
+}
+
static struct commit_list *find_bisection(struct commit_list *list,
int *reaches, int *all,
int find_all)
@@ -646,8 +728,11 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
save_commit_buffer = revs.verbose_header ||
revs.grep_filter.pattern_list;
- if (bisect_list)
+
+ if (bisect_list) {
+ for_each_tag_ref(bisect_replace, NULL);
revs.limited = 1;
+ }
if (prepare_revision_walk(&revs))
die("revision walk setup failed");
diff --git a/git-bisect.sh b/git-bisect.sh
index 0d0e278..245435c 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]'
+USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run|replace]'
LONG_USAGE='git bisect help
print this long help message.
git bisect start [<bad> [<good>...]] [--] [<pathspec>...]
@@ -23,6 +23,8 @@ git bisect log
show bisect log.
git bisect run <cmd>...
use <cmd>... to automatically bisect.
+git bisect replace <rev> [<rev>]
+ use another branch for bisection.
Please use "git help bisect" to get the full man page.'
@@ -618,6 +620,40 @@ bisect_run () {
done
}
+bisect_replace() {
+ test "$#" -ge 1 -a "$#" -le 2 ||
+ die "'git bisect replace' accept one or two arguments"
+
+ source="$1"
+ target="${2:-HEAD}"
+
+ # Check arguments
+ src_commit=$(git rev-parse --verify "$source^{commit}") ||
+ die "Bad rev input: $source"
+ tgt_commit=$(git rev-parse --verify "$target^{commit}") ||
+ die "Bad rev input: $target"
+
+ test "$src_commit" != "tgt_commit" ||
+ die "source and target should be different commits"
+
+ # Check that trees from source and target are identical
+ src_tree=$(git rev-parse --verify "$src_commit^{tree}") ||
+ die "Could not get tree for source: $source"
+ tgt_tree=$(git rev-parse --verify "$tgt_commit^{tree}") ||
+ die "Could not get tree for target: $target"
+
+ test "$src_tree" = "$tgt_tree" ||
+ die "source and target should point to the same tree"
+
+ # Tag the source commit
+ src_tag="bisect-replace-with-$tgt_commit"
+ git tag "$src_tag" "$src_commit" || exit
+
+ # Create branch for the target commit
+ tgt_branch="bisect-replace-$src_commit"
+ git branch "$tgt_branch" "$tgt_commit" || exit
+}
+
case "$#" in
0)
@@ -645,6 +681,8 @@ case "$#" in
cat "$GIT_DIR/BISECT_LOG" ;;
run)
bisect_run "$@" ;;
+ replace)
+ bisect_replace "$@" ;;
*)
usage ;;
esac
--
1.6.0.3.528.gad674
^ permalink raw reply related
* [PATCH] Add git-gui--askpass to git.spec.in
From: Yutaka Kanemoto @ 2008-11-04 17:15 UTC (permalink / raw)
To: git, gitster
'make rpm' will fail because git-gui--askpass is not listed in git.spec.in.
At least, I was able to create rpm using below patch.
Best regards,
Yutaka KANEMOTO
---
git.spec.in | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/git.spec.in b/git.spec.in
index 6733b6f..bf7fa63 100644
--- a/git.spec.in
+++ b/git.spec.in
@@ -167,6 +167,7 @@ rm -rf $RPM_BUILD_ROOT
%files gui
%defattr(-,root,root)
%{_libexecdir}/git-core/git-gui
+%{_libexecdir}/git-core/git-gui--askpass
%{_libexecdir}/git-core/git-citool
%{_datadir}/git-gui/
%{!?_without_docs: %{_mandir}/man1/git-gui.1*}
--
1.6.0.3.613.g9f8f13.dirty
^ permalink raw reply related
* [PATCH 5/5] git send-email: turn --compose on when more than one patch.
From: Pierre Habouzit @ 2008-11-04 16:24 UTC (permalink / raw)
To: git; +Cc: Pierre Habouzit
In-Reply-To: <1225815858-30617-5-git-send-email-madcoder@debian.org>
Automatically turn --compose on when there is more than one patch, and
that the output is a tty.
Do not print the list of files sent anymore in that case, as the list is
shown in the summary editor.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
git-send-email.perl | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/git-send-email.perl b/git-send-email.perl
index fd72127..3c7818f 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -51,7 +51,7 @@ git send-email [options] <file | directory | rev-list options >
--subject <str> * Email "Subject:"
--in-reply-to <str> * Email "In-Reply-To:"
--annotate * Review each patch that will be sent in an editor.
- --compose * Open an editor for introduction.
+ --[no-]compose * Open an editor for introduction.
Sending:
--envelope-sender <str> * Email envelope sender.
@@ -237,7 +237,7 @@ my $rc = GetOptions("sender|from=s" => \$sender,
"smtp-encryption=s" => \$smtp_encryption,
"identity=s" => \$identity,
"annotate" => \$annotate,
- "compose" => \$compose,
+ "compose!" => \$compose,
"quiet" => \$quiet,
"cc-cmd=s" => \$cc_cmd,
"suppress-from!" => \$suppress_from,
@@ -425,7 +425,11 @@ if ($validate) {
}
if (@files) {
- unless ($quiet) {
+ if (!defined($compose) && -t STDOUT) {
+ # turn $compose on if there is more than one file
+ $compose = $#files;
+ }
+ unless ($quiet || $compose) {
print $_,"\n" for (@files);
}
} else {
--
1.5.6.5
^ permalink raw reply related
* [PATCH 4/5] git send-email: ask less questions when --compose is used.
From: Pierre Habouzit @ 2008-11-04 16:24 UTC (permalink / raw)
To: git; +Cc: Pierre Habouzit
In-Reply-To: <1225815858-30617-4-git-send-email-madcoder@debian.org>
When --compose is used, we can grab the From/Subject/In-Reply-To from the
edited summary, let it be so and don't ask the user silly questions.
The summary templates gets quite revamped, and includes the list of
patches subjects that are going to be sent with this batch.
When having a body full of empty lines, the summary isn't sent. Document
that in the git-send-email manpage fully.
Note: It doesn't deal with To/Cc/Bcc yet.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
Documentation/git-send-email.txt | 9 ++
git-send-email.perl | 177 ++++++++++++++++++++++---------------
2 files changed, 114 insertions(+), 72 deletions(-)
diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index 39d6da9..e06db6b 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -45,6 +45,15 @@ The --cc option must be repeated for each user you want on the cc list.
--compose::
Use $GIT_EDITOR, core.editor, $VISUAL, or $EDITOR to edit an
introductory message for the patch series.
++
+When compose is in used, git send-email gets less interactive will use the
+values of the headers you set there. If the body of the email (what you type
+after the headers and a blank line) only contains blank (or GIT: prefixed)
+lines, the summary won't be sent, but git-send-email will still use the
+Headers values if you don't removed them.
++
+If it wasn't able to see a header in the summary it will ask you about it
+interactively after quitting your editor.
--from::
Specify the sender of the emails. This will default to
diff --git a/git-send-email.perl b/git-send-email.perl
index d0c5a41..fd72127 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -433,6 +433,108 @@ if (@files) {
usage();
}
+sub get_patch_subject($) {
+ my $fn = shift;
+ open (my $fh, '<', $fn);
+ while (my $line = <$fh>) {
+ next unless ($line =~ /^Subject: (.*)$/);
+ close $fh;
+ return "GIT: $1\n";
+ }
+ close $fh;
+ die "No subject line in $fn ?";
+}
+
+if ($compose) {
+ # Note that this does not need to be secure, but we will make a small
+ # effort to have it be unique
+ open(C,">",$compose_filename)
+ or die "Failed to open for writing $compose_filename: $!";
+
+
+ my $tpl_sender = $sender || $repoauthor || $repocommitter || '';
+ my $tpl_subject = $initial_subject || '';
+ my $tpl_reply_to = $initial_reply_to || '';
+
+ print C <<EOT;
+From $tpl_sender # This line is ignored.
+GIT: Lines beginning in "GIT: " will be removed.
+GIT: Consider including an overall diffstat or table of contents
+GIT: for the patch you are writing.
+GIT:
+GIT: Clear the body content if you don't wish to send a summary.
+From: $tpl_sender
+Subject: $tpl_subject
+In-Reply-To: $tpl_reply_to
+
+EOT
+ for my $f (@files) {
+ print C get_patch_subject($f);
+ }
+ close(C);
+
+ my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
+
+ if ($annotate) {
+ do_edit($compose_filename, @files);
+ } else {
+ do_edit($compose_filename);
+ }
+
+ open(C2,">",$compose_filename . ".final")
+ or die "Failed to open $compose_filename.final : " . $!;
+
+ open(C,"<",$compose_filename)
+ or die "Failed to open $compose_filename : " . $!;
+
+ my $need_8bit_cte = file_has_nonascii($compose_filename);
+ my $in_body = 0;
+ my $summary_empty = 1;
+ while(<C>) {
+ next if m/^GIT: /;
+ if ($in_body) {
+ $summary_empty = 0 unless (/^\n$/);
+ } elsif (/^\n$/) {
+ $in_body = 1;
+ if ($need_8bit_cte) {
+ print C2 "MIME-Version: 1.0\n",
+ "Content-Type: text/plain; ",
+ "charset=utf-8\n",
+ "Content-Transfer-Encoding: 8bit\n";
+ }
+ } elsif (/^MIME-Version:/i) {
+ $need_8bit_cte = 0;
+ } elsif (/^Subject:\s*(.+)\s*$/i) {
+ $initial_subject = $1;
+ my $subject = $initial_subject;
+ $_ = "Subject: " .
+ ($subject =~ /[^[:ascii:]]/ ?
+ quote_rfc2047($subject) :
+ $subject) .
+ "\n";
+ } elsif (/^In-Reply-To:\s*(.+)\s*$/i) {
+ $initial_reply_to = $1;
+ next;
+ } elsif (/^From:\s*(.+)\s*$/i) {
+ $sender = $1;
+ next;
+ } elsif (/^(?:To|Cc|Bcc):/i) {
+ print "To/Cc/Bcc fields are not interpreted yet, they have been ignored\n";
+ next;
+ }
+ print C2 $_;
+ }
+ close(C);
+ close(C2);
+
+ if ($summary_empty) {
+ print "Summary email is empty, skpping it\n";
+ $compose = -1;
+ }
+} elsif ($annotate) {
+ do_edit(@files);
+}
+
my $prompting = 0;
if (!defined $sender) {
$sender = $repoauthor || $repocommitter || '';
@@ -477,17 +579,6 @@ sub expand_aliases {
@initial_cc = expand_aliases(@initial_cc);
@bcclist = expand_aliases(@bcclist);
-if (!defined $initial_subject && $compose) {
- while (1) {
- $_ = $term->readline("What subject should the initial email start with? ", $initial_subject);
- last if defined $_;
- print "\n";
- }
-
- $initial_subject = $_;
- $prompting++;
-}
-
if ($thread && !defined $initial_reply_to && $prompting) {
while (1) {
$_= $term->readline("Message-ID to be used as In-Reply-To for the first email? ", $initial_reply_to);
@@ -514,64 +605,6 @@ if (!defined $smtp_server) {
}
if ($compose) {
- # Note that this does not need to be secure, but we will make a small
- # effort to have it be unique
- open(C,">",$compose_filename)
- or die "Failed to open for writing $compose_filename: $!";
- print C "From $sender # This line is ignored.\n";
- printf C "Subject: %s\n\n", $initial_subject;
- printf C <<EOT;
-GIT: Please enter your email below.
-GIT: Lines beginning in "GIT: " will be removed.
-GIT: Consider including an overall diffstat or table of contents
-GIT: for the patch you are writing.
-
-EOT
- close(C);
-
- my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
-
- if ($annotate) {
- do_edit($compose_filename, @files);
- } else {
- do_edit($compose_filename);
- }
-
- open(C2,">",$compose_filename . ".final")
- or die "Failed to open $compose_filename.final : " . $!;
-
- open(C,"<",$compose_filename)
- or die "Failed to open $compose_filename : " . $!;
-
- my $need_8bit_cte = file_has_nonascii($compose_filename);
- my $in_body = 0;
- while(<C>) {
- next if m/^GIT: /;
- if (!$in_body && /^\n$/) {
- $in_body = 1;
- if ($need_8bit_cte) {
- print C2 "MIME-Version: 1.0\n",
- "Content-Type: text/plain; ",
- "charset=utf-8\n",
- "Content-Transfer-Encoding: 8bit\n";
- }
- }
- if (!$in_body && /^MIME-Version:/i) {
- $need_8bit_cte = 0;
- }
- if (!$in_body && /^Subject: ?(.*)/i) {
- my $subject = $1;
- $_ = "Subject: " .
- ($subject =~ /[^[:ascii:]]/ ?
- quote_rfc2047($subject) :
- $subject) .
- "\n";
- }
- print C2 $_;
- }
- close(C);
- close(C2);
-
while (1) {
$_ = $term->readline("Send this email? (y|n) ");
last if defined $_;
@@ -583,9 +616,9 @@ EOT
exit(0);
}
- @files = ($compose_filename . ".final", @files);
-} elsif ($annotate) {
- do_edit(@files);
+ if ($compose > 0) {
+ @files = ($compose_filename . ".final", @files);
+ }
}
# Variables we set as part of the loop over files
--
1.5.6.5
^ permalink raw reply related
* [PATCH 3/5] git send-email: add --annotate option
From: Pierre Habouzit @ 2008-11-04 16:24 UTC (permalink / raw)
To: git; +Cc: Pierre Habouzit
In-Reply-To: <1225815858-30617-3-git-send-email-madcoder@debian.org>
This allows to review every patch (and fix various aspects of them, or
comment them) in an editor just before being sent. Combined to the fact
that git send-email can now process revision lists, this makes git
send-email and efficient way to review and send patches interactively.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
Documentation/git-send-email.txt | 11 +++++++++++
git-send-email.perl | 26 ++++++++++++++++++++++++--
2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index 4654d4f..39d6da9 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -37,6 +37,11 @@ The --bcc option must be repeated for each user you want on the bcc list.
+
The --cc option must be repeated for each user you want on the cc list.
+--annotate::
+ Review each patch you're about to send in an editor. The setting
+ 'sendemail.multiedit' defines if this will spawn one editor per patch
+ or one for all of them at once.
+
--compose::
Use $GIT_EDITOR, core.editor, $VISUAL, or $EDITOR to edit an
introductory message for the patch series.
@@ -204,6 +209,12 @@ sendemail.aliasfiletype::
Format of the file(s) specified in sendemail.aliasesfile. Must be
one of 'mutt', 'mailrc', 'pine', or 'gnus'.
+sendemail.multiedit::
+ If true (default), a single editor instance will be spawned to edit
+ files you have to edit (patches when '--annotate' is used, and the
+ summary when '--compose' is used). If false, files will be edited one
+ after the other, spawning a new editor each time.
+
Author
------
diff --git a/git-send-email.perl b/git-send-email.perl
index c29868a..d0c5a41 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -50,6 +50,7 @@ git send-email [options] <file | directory | rev-list options >
--bcc <str> * Email Bcc:
--subject <str> * Email "Subject:"
--in-reply-to <str> * Email "In-Reply-To:"
+ --annotate * Review each patch that will be sent in an editor.
--compose * Open an editor for introduction.
Sending:
@@ -129,7 +130,8 @@ sub cleanup_compose_files();
# Variables we fill in automatically, or via prompting:
my (@to,@cc,@initial_cc,@bcclist,@xh,
- $initial_reply_to,$initial_subject,@files,$author,$sender,$smtp_authpass,$compose,$time);
+ $initial_reply_to,$initial_subject,@files,
+ $author,$sender,$smtp_authpass,$annotate,$compose,$time);
my $envelope_sender;
@@ -151,6 +153,17 @@ if ($@) {
my ($quiet, $dry_run) = (0, 0);
my $compose_filename = $repo->repo_path() . "/.gitsendemail.msg.$$";
+# Handle interactive edition of files.
+my $multiedit;
+my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
+sub do_edit {
+ if (defined($multiedit) && !$multiedit) {
+ map { system('sh', '-c', $editor.' "$@"', $editor, $_); } @_;
+ } else {
+ system('sh', '-c', $editor.' "$@"', $editor, @_);
+ }
+}
+
# Variables with corresponding config settings
my ($thread, $chain_reply_to, $suppress_from, $signed_off_by_cc, $cc_cmd);
my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_encryption);
@@ -180,6 +193,7 @@ my %config_settings = (
"aliasesfile" => \@alias_files,
"suppresscc" => \@suppress_cc,
"envelopesender" => \$envelope_sender,
+ "multiedit" => \$multiedit,
);
# Handle Uncouth Termination
@@ -222,6 +236,7 @@ my $rc = GetOptions("sender|from=s" => \$sender,
"smtp-ssl" => sub { $smtp_encryption = 'ssl' },
"smtp-encryption=s" => \$smtp_encryption,
"identity=s" => \$identity,
+ "annotate" => \$annotate,
"compose" => \$compose,
"quiet" => \$quiet,
"cc-cmd=s" => \$cc_cmd,
@@ -515,7 +530,12 @@ EOT
close(C);
my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
- system('sh', '-c', $editor.' "$@"', $editor, $compose_filename);
+
+ if ($annotate) {
+ do_edit($compose_filename, @files);
+ } else {
+ do_edit($compose_filename);
+ }
open(C2,">",$compose_filename . ".final")
or die "Failed to open $compose_filename.final : " . $!;
@@ -564,6 +584,8 @@ EOT
}
@files = ($compose_filename . ".final", @files);
+} elsif ($annotate) {
+ do_edit(@files);
}
# Variables we set as part of the loop over files
--
1.5.6.5
^ permalink raw reply related
* [PATCH 2/5] git send-email: interpret unknown files as revision lists
From: Pierre Habouzit @ 2008-11-04 16:24 UTC (permalink / raw)
To: git; +Cc: Pierre Habouzit
In-Reply-To: <1225815858-30617-2-git-send-email-madcoder@debian.org>
Filter out all the arguments git-send-email doesn't like to a
git format-patch command, that dumps its content to a safe directory.
Barf when a file/revision conflict occurs.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
Documentation/git-send-email.txt | 2 +-
git-send-email.perl | 28 ++++++++++++++++++++++++----
2 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index 82f5056..4654d4f 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -8,7 +8,7 @@ git-send-email - Send a collection of patches as emails
SYNOPSIS
--------
-'git send-email' [options] <file|directory> [... file|directory]
+'git send-email' [options] <file|directory|rev-list options>...
DESCRIPTION
diff --git a/git-send-email.perl b/git-send-email.perl
index aaace02..c29868a 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -22,8 +22,11 @@ use Term::ReadLine;
use Getopt::Long;
use Data::Dumper;
use Term::ANSIColor;
+use File::Temp qw/ tempdir /;
use Git;
+Getopt::Long::Configure qw/ pass_through /;
+
package FakeTerm;
sub new {
my ($class, $reason) = @_;
@@ -38,7 +41,7 @@ package main;
sub usage {
print <<EOT;
-git send-email [options] <file | directory>...
+git send-email [options] <file | directory | rev-list options >
Composing:
--from <str> * Email From:
@@ -363,10 +366,22 @@ if (@alias_files and $aliasfiletype and defined $parse_alias{$aliasfiletype}) {
($sender) = expand_aliases($sender) if defined $sender;
+sub check_file_rev_conflict($) {
+ my $f = shift;
+ if ($repo->command('rev-parse', '--verify', '--quiet', $f)) {
+ die("revision/filename conflict on `$f'");
+ }
+}
+
# Now that all the defaults are set, process the rest of the command line
# arguments and collect up the files that need to be processed.
-for my $f (@ARGV) {
- if (-d $f) {
+my @rev_list_opts;
+while (my $f = pop @ARGV) {
+ if ($f eq "--") {
+ push @rev_list_opts, "--", @ARGV;
+ @ARGV = ();
+ } elsif (-d $f) {
+ check_file_rev_conflict($f);
opendir(DH,$f)
or die "Failed to opendir $f: $!";
@@ -374,12 +389,17 @@ for my $f (@ARGV) {
sort readdir(DH);
closedir(DH);
} elsif (-f $f or -p $f) {
+ check_file_rev_conflict($f);
push @files, $f;
} else {
- print STDERR "Skipping $f - not found.\n";
+ push @rev_list_opts, $f;
}
}
+if (@rev_list_opts) {
+ push @files, $repo->command('format-patch', '-o', tempdir(CLEANUP => 1), @rev_list_opts);
+}
+
if ($validate) {
foreach my $f (@files) {
unless (-p $f) {
--
1.5.6.5
^ permalink raw reply related
* [PATCH 1/5] git send-email: make the message file name more specific.
From: Pierre Habouzit @ 2008-11-04 16:24 UTC (permalink / raw)
To: git; +Cc: Pierre Habouzit
In-Reply-To: <1225815858-30617-1-git-send-email-madcoder@debian.org>
This helps editors choosing their syntax hilighting properly.
Also make the file live under the git directory.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
git-send-email.perl | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/git-send-email.perl b/git-send-email.perl
index 94ca5c8..aaace02 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -124,9 +124,6 @@ my $auth;
sub unique_email_list(@);
sub cleanup_compose_files();
-# Constants (essentially)
-my $compose_filename = ".msg.$$";
-
# Variables we fill in automatically, or via prompting:
my (@to,@cc,@initial_cc,@bcclist,@xh,
$initial_reply_to,$initial_subject,@files,$author,$sender,$smtp_authpass,$compose,$time);
@@ -149,6 +146,7 @@ if ($@) {
# Behavior modification variables
my ($quiet, $dry_run) = (0, 0);
+my $compose_filename = $repo->repo_path() . "/.gitsendemail.msg.$$";
# Variables with corresponding config settings
my ($thread, $chain_reply_to, $suppress_from, $signed_off_by_cc, $cc_cmd);
--
1.5.6.5
^ permalink raw reply related
* [take 2] git send-email updates
From: Pierre Habouzit @ 2008-11-04 16:24 UTC (permalink / raw)
To: git
In-Reply-To: <1225450632-7230-1-git-send-email-madcoder@debian.org>
[PATCH 1/5] git send-email: make the message file name more specific.
self described
[PATCH 2/5] git send-email: interpret unknown files as revision lists
All unknown arguments are passed to git-format-patch at once,
checking for possible file/rev conflicts and dying in that case,
like Junio suggested.
[PATCH 3/5] git send-email: add --annotate option
same as before.
[PATCH 4/5] git send-email: ask less questions when --compose is used.
same as before, with an update wrt empty bodies. Still doesn't grok
To/Cc/Bcc. I would be really glad if a patch to deal with it was
appended to that series, but a patch that deals with Header
continuations well.
[PATCH 5/5] git send-email: turn --compose on when more than one patch.
This patch is probably controversial. I propose it not because I'm
lazy, I now have a 'git send' alias for the task that expands to
'send-email -C -C -M -n --annotate --compose --to'. I propose it
because I believe it's a good thing to make people write about their
stuff when there is a series and not a single patch. If they still
don't want to, they just have to clear the mail buffer at once.
The drawback is that it _may_ break some scripts, those people would
have to pass --no-compose to their send-email call to fix the
scripts.
I wouldn't complain if the patch gets dropped.
--
·O· Pierre Habouzit
··O madcoder@debian.org
OOO http://www.madism.org
^ permalink raw reply
* Re: libxdiff and patience diff
From: Pierre Habouzit @ 2008-11-04 16:15 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: davidel, Git ML
In-Reply-To: <alpine.DEB.1.00.0811041650510.24407@pacific.mpi-cbg.de>
[-- Attachment #1: Type: text/plain, Size: 2571 bytes --]
On Tue, Nov 04, 2008 at 03:57:44PM +0000, Johannes Schindelin wrote:
> Hi,
>
> On Tue, 4 Nov 2008, Pierre Habouzit wrote:
>
> > The nasty thing about the patience diff is that it still needs the usual
> > diff algorithm once it has split the file into chunks separated by
> > "unique lines".
>
> Actually, it should try to apply patience diff again in those chunks,
> separately.
yes it's what I do, but this has a fixed point as soon as you don't find
unique lines between the new found ones, or that that space is "empty".
E.g. you could have the two following hunks:
File A File B
1 2
2 1
1 2
2 1
1 2
2
1
The simple leading/trailing reduction will do nothing, and you don't
have any shared unique lines, on that you must apply the usual diff
algorithm.
> > So you cannot make really independant stuff. What I could do is put most
> > of the xpatience diff into xpatience.c but it would still have to use
> > some functions from xdiffi.c that are currently private, so it messes
> > somehow the files more than it's worth IMHO.
>
> I think it is better that you use the stuff from xdiffi.c through a well
> defined interface, i.e. _not_ mess up the code by mingling it together
> with the code in xdiffi.c. The code is hard enough to read already.
Hmmm. I'll see to that later, once I have something that works.
> Oh, BTW, "ha" is a hash of the lines which is used to make the line
> matching more performant. You will see a lot of "ha" comparisons before
> actually calling xdl_recmatch() for that reason. Incidentally, this is
> also the hash that I'd use for the hash multi-set I was referring to.
Yeah, that's what I assumed it would be.
> Oh, and I am not sure that it is worth your time trying to get it to run
> with the linear list, since you cannot reuse that code afterwards, and
> have to spend the same amount of time to redo it with the hash set.
Having the linear list (actually an array) work would show me I hook at
the proper place. Replacing a data structure doesn't makes me afraid
because I've split the functions properly.
> I am awfully short on time, so it will take some days until I can review
> what you have already, unfortunately.
NP, it was just in case, because I'm horribly stuck with that code right
now ;)
--
·O· Pierre Habouzit
··O madcoder@debian.org
OOO http://www.madism.org
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox