* Re: [PATCH v14 5/8] bisect: introduce --no-checkout support into porcelain.
From: Jonathan Nieder @ 2011-08-03 18:57 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jon Seymour, git, chriscool, j6t, jnareb
In-Reply-To: <7voc07ct9z.fsf@alter.siamese.dyndns.org>
Junio C Hamano wrote:
> Just a minor worry but I would not be surprised if somebody's "test"
> implementation barfs upon:
>
> test "--no-checkout" = "--no-checkout"
>
> mistaking the string with a dash at the beginning as an option unknown to
> it. That is why we often have "z$variable" in our comparison, like so:
>
> if test "z$BISECT_MODE" = "z--no-checkout"
Hmm.
$ git grep -e 'test "\$' | wc -l
712
$ git grep -e 'test ".\$' | wc -l
183
We are very inconsistent about such usage, generally, and of course
POSIX is very clear about the 'z' not being needed in a three-argument
"test" used for string comparison. Is there any platform that is
usable for git (e.g., that implements "$( ... )") and has that
problem?
^ permalink raw reply
* Re: [PATCH 1bis/2] Diff patterns for POSIX shells
From: Junio C Hamano @ 2011-08-03 18:53 UTC (permalink / raw)
To: Jeff King; +Cc: Giuseppe Bilotta, git, Junio C Hamano
In-Reply-To: <20110803093252.GA16351@sigill.intra.peff.net>
Jeff King <peff@peff.net> writes:
> On Wed, Aug 03, 2011 at 07:26:16AM +0200, Giuseppe Bilotta wrote:
>
>> All diffs following a function definition will have that function name
>> as chunck header, but this is the best we can do with the current
>> userdiff capabilities.
>
> Curious as to how this would look in git.git, I tried "git log -p"
> before and after your patches, and diffed the result. I noticed two
> things:
Hmm, sounds like a regression without much upside to me.
Thanks for looking.
^ permalink raw reply
* Re: [PATCH] Add option hooks.emaildiff to include full diff in post-receive-email
From: Junio C Hamano @ 2011-08-03 18:52 UTC (permalink / raw)
To: Jon Jensen; +Cc: git
In-Reply-To: <alpine.DEB.2.02.1108022132230.3386@ybpnyubfg6.ybpnyqbznva6>
Jon Jensen <jon@endpoint.com> writes:
> - echo "Summary of changes:"
> - git diff-tree --stat --summary --find-copies-harder $oldrev..$newrev
> + if [ -n "$emaildiff" ]; then
> + echo "Summary of changes and diff:"
> + git diff-tree --stat --summary --find-copies-harder -p $oldrev..$newrev
> + else
> + echo "Summary of changes:"
> + git diff-tree --stat --summary --find-copies-harder $oldrev..$newrev
> + fi
Depending on the project, people may want to customize other aspects of
the summary generation, e.g. rejecting the overhead of -f-c-h.
Why not do it like this intead?
diffopts=$(git config hooks.diffopts)
: ${diffopts:="--stat --summary --find-copies-harder"}
echo "Summary of changes:"
git diff-tree $diffopts $oldrev..$newrev
^ permalink raw reply
* Re: [PATCH 3/5] setup_revisions: remember whether a ref was positive or not
From: Junio C Hamano @ 2011-08-03 18:12 UTC (permalink / raw)
To: Sverre Rabbelier
Cc: Johannes Schindelin, Jonathan Nieder, Jeff King, Git List,
Daniel Barkalow, Ramkumar Ramachandra, Dmitry Ivankov
In-Reply-To: <CAGdFq_ghxFdpjxCgTNbqXWGpt0rpJaGZ1_h+ZC71PzaPzbQ-0A@mail.gmail.com>
Sverre Rabbelier <srabbelier@gmail.com> writes:
> On Sun, Jul 24, 2011 at 21:23, Junio C Hamano <gitster@pobox.com> wrote:
>> Sverre Rabbelier <srabbelier@gmail.com> writes:
>>
>>> void add_pending_object(struct rev_info *revs, struct object *obj, const char *name)
>>> {
>>> - add_pending_object_with_mode(revs, obj, name, S_IFINVALID);
>>> + add_pending_object_with_mode(revs, obj, name, S_IFINVALID, 0);
>>> }
>>
>> This seems utterly broken. For example, fmt-merge-msg.c adds "^HEAD" and
>> of course the flags on the object is UNINTERESTING. Has all the callers of
>> add_pending_object() been verified? Why is it passing an unconditional 0
>> and not !!(obj->flags & UNINTERESTING) or something?
>
> If I understand correctly (and it's not unlikely that I don't), the
> 'flags' field is used to store the actual flags (not just a boolean).
> Would the following be appropriate?
>
> + add_pending_object_with_mode(revs, obj, name, S_IFINVALID, obj->flags);
I would think that the information you are trying to convey is more in
line with the spirit of "name" field, not "mode". Originally, the pending
object array was to only collect the given arguments at the object level
with "is this interesting or uninteresting?" flag and nothing more, but we
later wanted to have richer information to deduce what the user wanted
from how the user gave the object information to us (i.e. "not just the
tree object named by the object name, but I meant the object at this
path"), primarily to give a better error message.
Let's clarify what I hinted as "some parsed representation of how the revs
were specified" in an earlier message with a concrete example. There is a
code block at the end of builtin/diff.c that says something like:
If we have more than 2 tree-ishes, and the first one is marked as
UNINTERESTING, it must have come from "diff A...B". In this case,
we know ent[0] is one of the merge-bases, ent[ents-2] is A, and
ent[ents-1] is B, so turn it into "diff ent[0] B".
These entries in ent[] come from the pending objects array, and because
the revision machinery loses information regarding how the command line
arguments were spelled, we have to play such games to _guess_ what the
user meant to say. This will lead to "diff ^C A B" running "diff C B",
instead of barfing with "What are you talking about???", which should
happen instead.
Wouldn't it be wonderful if the revision machinery left richer clue in
each element of the pending object array while parsing, so that the caller
does not have to guess? For example, suppose that it parsed "A...B" into
this N element array of pending objects:
^MB0 (the first merge base of A and B)
^MB1 (the second merge base of A and B)
...
A
B
In addition to a single "mode" integer, which says if it is supposed to be
a tree or a blob, we could allocate a single structure that records
something like this:
struct parsed_rev {
enum {
SHA1, REF, RANGE, SYMMETRIC_RANGE, REFLOG_ENT, ...
// there are others like OBJ^!, OBJ@!, ...
} kind;
const char *string;
union {
struct {
const char *real_ref;
} ref;
struct {
struct parsed_rev *bottom;
struct parsed_rev *top;
} range;
...
} u;
};
And then all the elements in the pending object array resulting from
parsing "maint...master" would all point at a single instance of this
"struct parsed_rev" that may read like this:
{
.kind = SYMMETRIC_RANGE;
.string = "maint...master";
.u.range = {
.bottom = {
.kind = REF;
.string = "maint";
.u.ref.real_ref = "refs/heads/maint";
};
.top = {
.kind = REF;
.string = "master";
.u.ref.real_ref = "refs/heads/master";
};
};
};
In a similar fashion, if you wanted to make sure that you do not discard
"master" as totally uninteresting, even though the end user gave you a
list of arguments that ends up marking the commit object "master" as
uninteresting, e.g. "master^0..master", you could do so if we updated the
revision parsing machinery so that the resulting two elements in the
pending array would both point at (in addition to the "uninteresting
commit object 'master^0'") a structure that would look like this:
{
.kind = RANGE;
.string = "master^0..master";
.u.range = {
...
.top = {
.kind = REF;
.string = "master";
.u.ref.real_ref = "refs/heads/master";
};
};
};
And by looking at .u.range.top, you know that the user meant to do
something to the "master" branch.
^ permalink raw reply
* [PATCH] add gitignore entry to description about how to write a builtin
From: Heiko Voigt @ 2011-08-03 18:06 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
If the author forgets the gitignore entry the built result will show up
as new file in the git working directory.
Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
---
Documentation/technical/api-builtin.txt | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/Documentation/technical/api-builtin.txt b/Documentation/technical/api-builtin.txt
index 5cb2b05..b0cafe8 100644
--- a/Documentation/technical/api-builtin.txt
+++ b/Documentation/technical/api-builtin.txt
@@ -49,6 +49,8 @@ Additionally, if `foo` is a new command, there are 3 more things to do:
. Add an entry for `git-foo` to `command-list.txt`.
+. Add an entry for `/git-foo` to `.gitignore`.
+
How a built-in is called
------------------------
--
1.7.6.353.g02057.dirty
^ permalink raw reply related
* [PATCH] add technical documentation about ref iteration
From: Heiko Voigt @ 2011-08-03 18:03 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
---
Documentation/technical/api-ref-iteration.txt | 73 +++++++++++++++++++++++++
1 files changed, 73 insertions(+), 0 deletions(-)
create mode 100644 Documentation/technical/api-ref-iteration.txt
diff --git a/Documentation/technical/api-ref-iteration.txt b/Documentation/technical/api-ref-iteration.txt
new file mode 100644
index 0000000..0a67e39
--- /dev/null
+++ b/Documentation/technical/api-ref-iteration.txt
@@ -0,0 +1,73 @@
+ref iteration API
+=================
+
+
+Iteration of refs is done by using an iterate function which will call a
+callback function for every ref. The callback function has this
+signature:
+
+ int handle_one_ref(const char *refname, const unsigned char *sha1,
+ int flags, void *cb_data);
+
+There are different kinds of iterate functions which all take a
+callback of this type. The callback is then called for each found ref
+until the callback returns nonzero. The returned value is then also
+returned by the iterate function.
+
+Iteration functions
+-------------------
+
+* `head_ref()` just iterates the head ref.
+
+* `for_each_ref()` iterates all refs.
+
+* `for_each_ref_in()` iterates all refs which have a defined prefix and
+ strips that prefix from the passed variable refname.
+
+* `for_each_tag_ref()`, `for_each_branch_ref()`, `for_each_remote_ref()`,
+ `for_each_replace_ref()` iterate refs from the respective area.
+
+* `for_each_glob_ref()` iterates all refs that match the specified glob
+ pattern.
+
+* `for_each_glob_ref_in()` the previous and `for_each_ref_in()` combined.
+
+* `head_ref_submodule()`, `for_each_ref_submodule()`,
+ `for_each_ref_in_submodule()`, `for_each_tag_ref_submodule()`,
+ `for_each_branch_ref_submodule()`, `for_each_remote_ref_submodule()`
+ do the same as the functions descibed above but for a specified
+ submodule.
+
+* `for_each_rawref()` can be used to learn about broken ref and symref.
+
+* `for_each_reflog()` iterates each reflog file.
+
+Submodules
+----------
+
+If you want to iterate the refs of a submodule you first need to call
+
+ add_submodule_odb(submodule)
+
+and test whether that succeeds.
+
+Example:
+--------
+
+----
+static int handle_remote_ref(const char *refname,
+ const unsigned char *sha1, int flags, void *cb_data)
+{
+ struct strbuf *output = cb_data;
+ strbuf_addf(output, "%s\n", refname);
+ return 0;
+}
+
+...
+
+ struct strbuf output = STRBUF_INIT;
+ for_each_remote_ref(handle_remote_ref, &output);
+ printf("%s", output.buf);
+----
+
+(Heiko Voigt)
--
1.7.6.353.g02057.dirty
^ permalink raw reply related
* Re: [PATCH 17/18] revert: Introduce --continue to continue the operation
From: Ramkumar Ramachandra @ 2011-08-03 17:59 UTC (permalink / raw)
To: Junio C Hamano
Cc: Christian Couder, Git List, Jonathan Nieder, Daniel Barkalow,
Jeff King
In-Reply-To: <7v4o1ycsi4.fsf@alter.siamese.dyndns.org>
Hi Junio,
Junio C Hamano writes:
> Ramkumar Ramachandra <artagnon@gmail.com> writes:
>>>> + for (p = buf.buf; *p; p = strchr(p, '\n') + 1) {
>>>
>>> This relies on a "\n" at the end of the last line...
>>
>> Yes, that was intentional. Every editor I know of inserts a '\n' at
>> the end of the last line,...
>
> Why do you think "diff" has a special codepath to report "No newline at
> end of file"? Because some editors do leave an incomplete line incomplete.
>
> When working on a "buf" with an incomplete line at the end, the last round
> of the loop will assign "(char *) 1" to "p", try to see "*p" is NUL and
> segfault, no?
Thanks for the excellent explanation! :)
I'll fix this and re-roll asap: I'll take the opportunity to include
the other changes that Christian suggested.
-- Ram
^ permalink raw reply
* Re: [RFC] Questions for "Git User's Survey 2011"
From: Jakub Narębski @ 2011-08-03 17:40 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason; +Cc: git
In-Reply-To: <CACBZZX5-KrzZ+WptqX__W9GBE8LxY24fSXSth3JpiJyDbrzN-Q@mail.gmail.com>
On 8/3/11, Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:
> 2011/7/25 Jakub Narebski <jnareb@gmail.com>:
>
>> === 16. Which of the following Git features do you use? ===
>> (multiple choice, with other)
>>
>> + localization of command-line messages (i18n)
>
> It's probably better to move this to some "would you like i18n"
> section. Nobody can use i18n at the moment, there's just a skeleton
> implementation of it.
O.K. I moved it to "17. Which of the following features would you
like to see implemented in git?"
Thanks for feedback
--
Jakub Narebski
^ permalink raw reply
* Re: [PATCH 17/18] revert: Introduce --continue to continue the operation
From: Junio C Hamano @ 2011-08-03 17:30 UTC (permalink / raw)
To: Ramkumar Ramachandra
Cc: Christian Couder, Git List, Jonathan Nieder, Daniel Barkalow,
Jeff King
In-Reply-To: <CALkWK0mrx+3jdCQD9xya3AWMsPpSiZzEz+Z9XVxZNzw3UdKMVw@mail.gmail.com>
Ramkumar Ramachandra <artagnon@gmail.com> writes:
>>> + for (p = buf.buf; *p; p = strchr(p, '\n') + 1) {
>>
>> This relies on a "\n" at the end of the last line...
>
> Yes, that was intentional. Every editor I know of inserts a '\n' at
> the end of the last line,...
Why do you think "diff" has a special codepath to report "No newline at
end of file"? Because some editors do leave an incomplete line incomplete.
When working on a "buf" with an incomplete line at the end, the last round
of the loop will assign "(char *) 1" to "p", try to see "*p" is NUL and
segfault, no?
^ permalink raw reply
* Re: tracking submodules out of main directory.
From: Junio C Hamano @ 2011-08-03 17:11 UTC (permalink / raw)
To: henri GEIST
Cc: Heiko Voigt, Jens Lehmann, Alexei Sholik, git, Sverre Rabbelier
In-Reply-To: <1312374382.3261.913.camel@Naugrim.eriador.com>
henri GEIST <henri.geist@flying-robots.com> writes:
> I plan to use a config file containing lines like
>
> "path_to_poited_repo SHA1_of_intended_commit URL_of_origin"
>
> the URL part will not be required.
>
> this file will be a list of pointer to other project.
I wasn't paying attention to this thread, but I have to ask "why" here.
The first two are what gitlink was designed to do in the superproject that
ties multiple submodules together, and the last one is also supplied by
the .gitmodules in that superproject. This seems to be adding the same
information in a redundant way by saying "this version A0 of submodule A
wants version B0 of submodule B and version C0 of submodule C" when the
supermodule can say "the consistent view I record is to have version A0,
B0 and C0 of submodules A, B and C, respectively".
I also suspect that allowing each submodule to know and demand specific
versions of other submodules will lead to inconsistencies. Which version
of submodule C would you demand to have when submodule A wants version C0
and submodule B wants version C1 of it?
^ permalink raw reply
* Re: [PATCH v14 5/8] bisect: introduce --no-checkout support into porcelain.
From: Junio C Hamano @ 2011-08-03 17:01 UTC (permalink / raw)
To: Jon Seymour; +Cc: git, chriscool, j6t, jnareb
In-Reply-To: <CAH3AnrpPaUY1fj9thMybPUgeM=mBEN3FjawjiR2vhw4S-v6qyg@mail.gmail.com>
Jon Seymour <jon.seymour@gmail.com> writes:
> I had a quick go at doing this, but haven't been able to test it
> fully. At a minimum it will require that we relax the barriers in
> git-bisect.sh and git.c that prevent git-bisect
> and bisect--helper running without a working tree. Other paths in
> these modules will need to be checked to see that they don't have an
> implicit assumption that a working tree is available.
>
> I won't have time to tackle this properly until the weekend.
That is Ok and thanks for looking. Making this available to bare
repository is a totally separate follow-on topic that can and should be
done as a separate series that depends on the current topic anyway, so
let's focus on the current topic at hand first.
^ permalink raw reply
* git clone does not checkout active branch
From: Udo @ 2011-08-03 16:56 UTC (permalink / raw)
To: git
I have a remote bare repository with two branches 'master' and 'testing', where
HEAD refers to 'testing'. When cloning this repository git checks out 'master',
if 'master' and 'testing' are on the same revision (i.e. HEAD == testing ==
master). Only if 'testing' is one (or more) commit(s) behind or ahead, git clone
checks out the 'testing' branch on the local side. I tried this with git 1.7.5
on Mac OS X (10.6.8).
Addendum: I just tried the same with a non-bare repository:
mkdir A
cd A
git init
touch a
git add a
git commit -m "init repo A with a"
git checkout -b testing
now back in the root dir:
cd ..
git clone A B
cd B
git branch -v -a
* master 28f599b init A
remotes/origin/HEAD -> origin/master
remotes/origin/master 28f599b init A
remotes/origin/testing 28f599b init A
it's 'master'! Back to repo A (we are still in branch 'testing'):
cd ../A
touch b
git add b
git commit -m "add b in branch testing"
now 'testing' is one commit ahead 'master'. Now let's clone A again:
cd ..
git clone A C
cd C
git branch -a -v
* testing 23bca39 add b in branch testing
remotes/origin/HEAD -> origin/testing
remotes/origin/master 28f599b init A
remotes/origin/testing 23bca39 add b in branch testing
You can re-verify this weird behavior by going back to A, checkout 'master' and
merge it with 'testing' (so that all branches have the same head). Now clone A
into D and D will be checked out on master!
^ permalink raw reply
* Re: [PATCH] For Real - Fixed pluralization in diff reports
From: Jon Forrest @ 2011-08-03 16:52 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git, gitster
In-Reply-To: <m3livdqh9h.fsf@localhost.localdomain>
On 8/3/2011 6:38 AM, Jakub Narebski wrote:
> Jon Forrest<nobozo@gmail.com> writes:
> Besides, as it was already said, this is an API.
I pretty much only looked at that one file and it
didn't look at quick glance like an API was being
used to internationalize git.
>> If the goal if the i18n effort is also to produce grammatically
>> correct output in all the supported languages then the
>> tests that my patch would break would have to be rewritten
>> anyway.
>
> That's not it.
We can discuss the correct way to implement a change like this
but the fact remains that whatever the implementation, the issue
that Junio raised will remain. That is, what to do about all
the places that presume the old incorrect output.
This problem isn't specific to git. I can easily imagine
other open source projects that face, or will face, this
problem.
Jon
^ permalink raw reply
* Re: [RFC] Questions for "Git User's Survey 2011"
From: Ævar Arnfjörð Bjarmason @ 2011-08-03 16:40 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <201107252233.02088.jnareb@gmail.com>
2011/7/25 Jakub Narebski <jnareb@gmail.com>:
> === 16. Which of the following Git features do you use? ===
> (multiple choice, with other)
>
> + localization of command-line messages (i18n)
It's probably better to move this to some "would you like i18n"
section. Nobody can use i18n at the moment, there's just a skeleton
implementation of it.
^ permalink raw reply
* Re: [PATCH v15 5/7] bisect: introduce --no-checkout support into porcelain.
From: Jon Seymour @ 2011-08-03 15:32 UTC (permalink / raw)
To: git; +Cc: chriscool, gitster, j6t, jnareb, Jon Seymour
In-Reply-To: <1312383811-7130-6-git-send-email-jon.seymour@gmail.com>
On Thu, Aug 4, 2011 at 1:03 AM, Jon Seymour <jon.seymour@gmail.com> wrote:
rm -f "$GIT_DIR/head-name" &&
> -
> - rm -f "$GIT_DIR/BISECT_START"
> + rm -f "$GIT_DIR/BISECT_START" &&
> + git update-ref -d BISECT_HEAD
> }
I'll reverse the order of the last two statements and restore the blank line...
jon.
^ permalink raw reply
* Re: [PATCH v14 5/8] bisect: introduce --no-checkout support into porcelain.
From: Jon Seymour @ 2011-08-03 15:24 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, chriscool, j6t, jnareb
In-Reply-To: <CAH3AnrrtfhU1r1DWO8ski5Jd=cLXcj3Wq-MowB8QKv+r1-BT_A@mail.gmail.com>
On Wed, Aug 3, 2011 at 11:16 PM, Jon Seymour <jon.seymour@gmail.com> wrote:
> On Wed, Aug 3, 2011 at 9:16 AM, Junio C Hamano <gitster@pobox.com> wrote:
>> Junio C Hamano <gitster@pobox.com> writes:
>>
>>> Jon Seymour <jon.seymour@gmail.com> writes:
>>
>> Further polishing we may want to do while it is still in pu/next I can
>> think of off the top of my head are:
>>
>> - In this mode, I can bisect the history even inside a bare repository,
>> as the whole point of --no-checkout is that the mode does not require a
>> working tree. I however suspect "git bisect" requires working tree. Is
>> this something we want to fix?
>>
>
> I agree, that would be useful. Haven't tried it yet but I'll see what
> happens.I may issue changes for this as separate commit that can be
> squashed later, if required, once it has been reviewed.
>
I had a quick go at doing this, but haven't been able to test it
fully. At a minimum it will require that we relax the barriers in
git-bisect.sh and git.c that prevent git-bisect
and bisect--helper running without a working tree. Other paths in
these modules will need to be checked to see that they don't have an
implicit assumption that a working tree is available.
I won't have time to tackle this properly until the weekend.
jon.
^ permalink raw reply
* Re: [PATCH v13 5/8] bisect: introduce --no-checkout support into porcelain.
From: Jon Seymour @ 2011-08-03 15:13 UTC (permalink / raw)
To: Christian Couder; +Cc: Christian Couder, git, gitster, j6t, jnareb
In-Reply-To: <CAP8UFD3QvXv_gnAtw3qMCOdDyAUAFMYcf33ieP+HebvTf3SGAg@mail.gmail.com>
On Thu, Aug 4, 2011 at 12:09 AM, Christian Couder
<christian.couder@gmail.com> wrote:
> On Wed, Aug 3, 2011 at 3:24 PM, Jon Seymour <jon.seymour@gmail.com> wrote:
>> On Wed, Aug 3, 2011 at 10:46 PM, Jon Seymour <jon.seymour@gmail.com> wrote:
>>> On Wed, Aug 3, 2011 at 3:27 PM, Christian Couder
>>> <chriscool@tuxfamily.org> wrote:
>>>> On Tuesday 02 August 2011 16:41:13 Jon Seymour wrote:
>>>>> On Tue, Aug 2, 2011 at 10:04 PM, Christian Couder
>>>>>
>>>>> If I was to do this, I'd prefer to change uses of $BISECT_MODE with a
>>>>> call to a function bisect_mode() that does the same thing.
>>>>
>>>> Yeah, I think it would be a good idea to have a bisect_mode() function.
>>>> I don't like very much to blindly call some code when we might not need it.
>>>>
>>>
>> Mmmm.
>>
>> Actually, there is a neater way to do this.
>>
>> I'll such use the existence of BISECT_HEAD to inform the
>> implementation of bisect_mode().
>>
>> This avoids the need for a separate .git/BISECT_MODE file.
>
> Yeah, but then you have to be careful of the fact that BISECT_HEAD
> might have not been properly deleted or might have been created by the
> user for other purposes.
>
I have removed $GIT_DIR/BISECT_MODE in v15.
If BISECT_HEAD was being used for other purposes, it is going to get
deleted anyway, irrespective of whether we have a separate BISECT_MODE
file, so I am not sure we need to consider that when deciding when we
need a separate BISECT_MODE file.
FWIW: bisect_mode() was only going to get called from one place so I
just inlined the implementation in that place. (on the call to
bisect--helper).
jon.
^ permalink raw reply
* [PATCH v15 7/7] bisect: add documentation for --no-checkout option.
From: Jon Seymour @ 2011-08-03 15:03 UTC (permalink / raw)
To: git; +Cc: chriscool, gitster, j6t, jnareb, Jon Seymour
In-Reply-To: <1312383811-7130-1-git-send-email-jon.seymour@gmail.com>
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
Documentation/git-bisect.txt | 32 +++++++++++++++++++++++++++++++-
1 files changed, 31 insertions(+), 1 deletions(-)
diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt
index ab60a18..2f23829 100644
--- a/Documentation/git-bisect.txt
+++ b/Documentation/git-bisect.txt
@@ -17,7 +17,7 @@ The command takes various subcommands, and different options depending
on the subcommand:
git bisect help
- git bisect start [<bad> [<good>...]] [--] [<paths>...]
+ git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<paths>...]
git bisect bad [<rev>]
git bisect good [<rev>...]
git bisect skip [(<rev>|<range>)...]
@@ -263,6 +263,17 @@ rewind the tree to the pristine state. Finally the script should exit
with the status of the real test to let the "git bisect run" command loop
determine the eventual outcome of the bisect session.
+OPTIONS
+-------
+--no-checkout::
++
+Do not checkout the new working tree at each iteration of the bisection
+process. Instead just update a special reference named 'BISECT_HEAD' to make
+it point to the commit that should be tested.
++
+This option is useful in circumstances in which checkout is either not
+possible (because the repository is damaged) or is otherwise not required.
+
EXAMPLES
--------
@@ -343,6 +354,25 @@ $ git bisect run sh -c "make || exit 125; ~/check_test_case.sh"
This shows that you can do without a run script if you write the test
on a single line.
+* Locate a good region of the object graph in a damaged repository
++
+------------
+$ git bisect start HEAD <known-good-commit> [ <boundary-commit> ... ] --no-checkout
+$ git bisect run eval '
+rc=1;
+if git rev-list --objects BISECT_HEAD >tmp.$$; then
+ git pack-objects --stdout >/dev/null < tmp.$$ && rc=0;
+fi;
+rm tmp.$$;
+test $rc -eq 0;'
+
+------------
++
+In this case, when 'git bisect run' finishes, bisect/bad will refer to a commit that
+has at least one parent whose reachable graph is fully traversable in the sense
+required by 'git pack objects'.
+
+
SEE ALSO
--------
link:git-bisect-lk2009.html[Fighting regressions with git bisect],
--
1.7.6.352.gd542a2
^ permalink raw reply related
* [PATCH v15 5/7] bisect: introduce --no-checkout support into porcelain.
From: Jon Seymour @ 2011-08-03 15:03 UTC (permalink / raw)
To: git; +Cc: chriscool, gitster, j6t, jnareb, Jon Seymour
In-Reply-To: <1312383811-7130-1-git-send-email-jon.seymour@gmail.com>
git-bisect can now perform bisection of a history without performing
a checkout at each stage of the bisection process. Instead, HEAD is updated.
One use-case for this function is allow git bisect to be used with
damaged repositories where git checkout would fail because the tree
referenced by the commit is damaged.
It can also be used in other cases where actual checkout of the tree
is not required to progress the bisection.
Improved-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
git-bisect.sh | 42 +++++++++++++++++++++++++++++++-----------
1 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/git-bisect.sh b/git-bisect.sh
index a44ffe1..bebc6cd 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -3,7 +3,7 @@
USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]'
LONG_USAGE='git bisect help
print this long help message.
-git bisect start [<bad> [<good>...]] [--] [<pathspec>...]
+git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]
reset bisect state and start bisection.
git bisect bad [<rev>]
mark <rev> a known-bad revision.
@@ -34,6 +34,15 @@ require_work_tree
_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
+bisect_head()
+{
+ if test -f "$GIT_DIR/BISECT_HEAD"; then
+ echo BISECT_HEAD;
+ else
+ echo HEAD
+ fi
+}
+
bisect_autostart() {
test -s "$GIT_DIR/BISECT_START" || {
(
@@ -69,6 +78,7 @@ bisect_start() {
orig_args=$(git rev-parse --sq-quote "$@")
bad_seen=0
eval=''
+ mode=''
while [ $# -gt 0 ]; do
arg="$1"
case "$arg" in
@@ -76,6 +86,11 @@ bisect_start() {
shift
break
;;
+ --no-checkout)
+ mode=--no-checkout;
+ shift ;;
+ --*)
+ die "$(eval_gettext "unrecognised option: '\$arg'")" ;;
*)
rev=$(git rev-parse -q --verify "$arg^{commit}") || {
test $has_double_dash -eq 1 &&
@@ -107,7 +122,9 @@ bisect_start() {
then
# Reset to the rev from where we started.
start_head=$(cat "$GIT_DIR/BISECT_START")
- git checkout "$start_head" -- || exit
+ if test "$mode" != "--no-checkout"; then
+ git checkout "$start_head" --
+ fi
else
# Get rev from where we start.
case "$head" in
@@ -143,6 +160,8 @@ bisect_start() {
#
# Write new start state.
#
+ test "$mode" != "--no-checkout" ||
+ git update-ref --no-deref BISECT_HEAD "$start_head" &&
echo "$start_head" >"$GIT_DIR/BISECT_START" &&
git rev-parse --sq-quote "$@" >"$GIT_DIR/BISECT_NAMES" &&
eval "$eval true" &&
@@ -206,8 +225,8 @@ bisect_state() {
0,*)
die "$(gettext "Please call 'bisect_state' with at least one argument.")" ;;
1,bad|1,good|1,skip)
- rev=$(git rev-parse --verify HEAD) ||
- die "$(gettext "Bad rev input: HEAD")"
+ rev=$(git rev-parse --verify $(bisect_head)) ||
+ die "$(gettext "Bad rev input: $(bisect_head)")"
bisect_write "$state" "$rev"
check_expected_revs "$rev" ;;
2,bad|*,good|*,skip)
@@ -291,7 +310,7 @@ bisect_next() {
bisect_next_check good
# Perform all bisection computation, display and checkout
- git bisect--helper --next-all
+ git bisect--helper --next-all $(test -f "$GIT_DIR/BISECT_HEAD" && echo --no-checkout)
res=$?
# Check if we should exit because bisection is finished
@@ -340,12 +359,13 @@ bisect_reset() {
*)
usage ;;
esac
- if git checkout "$branch" -- ; then
- bisect_clean_state
- else
- die "$(eval_gettext "Could not check out original HEAD '\$branch'.
+ if ! test -f "$GIT_DIR/BISECT_HEAD"; then
+ if ! git checkout "$branch" --; then
+ die "$(eval_gettext "Could not check out original HEAD '\$branch'.
Try 'git bisect reset <commit>'.")"
+ fi
fi
+ bisect_clean_state
}
bisect_clean_state() {
@@ -362,8 +382,8 @@ bisect_clean_state() {
rm -f "$GIT_DIR/BISECT_RUN" &&
# Cleanup head-name if it got left by an old version of git-bisect
rm -f "$GIT_DIR/head-name" &&
-
- rm -f "$GIT_DIR/BISECT_START"
+ rm -f "$GIT_DIR/BISECT_START" &&
+ git update-ref -d BISECT_HEAD
}
bisect_replay () {
--
1.7.6.352.gd542a2
^ permalink raw reply related
* [PATCH v15 6/7] bisect: add tests for the --no-checkout option.
From: Jon Seymour @ 2011-08-03 15:03 UTC (permalink / raw)
To: git; +Cc: chriscool, gitster, j6t, jnareb, Jon Seymour
In-Reply-To: <1312383811-7130-1-git-send-email-jon.seymour@gmail.com>
These tests verify that git-bisect --no-checkout can successfully
bisect commit histories that reference damaged trees.
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
t/t6030-bisect-porcelain.sh | 82 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 82 insertions(+), 0 deletions(-)
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 9ae2de8..1c05135 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -126,6 +126,18 @@ test_expect_success 'bisect reset removes packed refs' '
test -z "$(git for-each-ref "refs/heads/bisect")"
'
+test_expect_success 'bisect reset removes bisect state after --no-checkout' '
+ git bisect reset &&
+ git bisect start --no-checkout &&
+ git bisect good $HASH1 &&
+ git bisect bad $HASH3 &&
+ git bisect next &&
+ git bisect reset &&
+ test -z "$(git for-each-ref "refs/bisect/*")" &&
+ test -z "$(git for-each-ref "refs/heads/bisect")" &&
+ test -z "$(git for-each-ref "BISECT_HEAD")"
+'
+
test_expect_success 'bisect start: back in good branch' '
git branch > branch.output &&
grep "* other" branch.output > /dev/null &&
@@ -616,6 +628,14 @@ cat > expected.missing-tree.default <<EOF
fatal: unable to read tree 39f7e61a724187ab767d2e08442d9b6b9dab587d
EOF
+check_same()
+{
+ echo "Checking $1 is the same as $2" &&
+ git rev-parse "$1" > expected.same &&
+ git rev-parse "$2" > expected.actual &&
+ test_cmp expected.same expected.actual
+}
+
test_expect_success 'bisect fails if tree is broken on start commit' '
git bisect reset &&
test_must_fail git bisect start BROKEN_HASH7 BROKEN_HASH4 2>error.txt &&
@@ -630,4 +650,66 @@ test_expect_success 'bisect fails if tree is broken on trial commit' '
test_cmp expected.missing-tree.default error.txt
'
+test_expect_success 'bisect: --no-checkout - start commit bad' '
+ git bisect reset &&
+ git bisect start BROKEN_HASH7 BROKEN_HASH4 --no-checkout &&
+ check_same BROKEN_HASH6 BISECT_HEAD &&
+ git bisect reset
+'
+
+test_expect_success 'bisect: --no-checkout - trial commit bad' '
+ git bisect reset &&
+ git bisect start broken BROKEN_HASH4 --no-checkout &&
+ check_same BROKEN_HASH6 BISECT_HEAD &&
+ git bisect reset
+'
+
+test_expect_success 'bisect: --no-checkout - target before breakage' '
+ git bisect reset &&
+ git bisect start broken BROKEN_HASH4 --no-checkout &&
+ check_same BROKEN_HASH6 BISECT_HEAD &&
+ git bisect bad BISECT_HEAD &&
+ check_same BROKEN_HASH5 BISECT_HEAD &&
+ git bisect bad BISECT_HEAD &&
+ check_same BROKEN_HASH5 bisect/bad &&
+ git bisect reset
+'
+
+test_expect_success 'bisect: --no-checkout - target in breakage' '
+ git bisect reset &&
+ git bisect start broken BROKEN_HASH4 --no-checkout &&
+ check_same BROKEN_HASH6 BISECT_HEAD &&
+ git bisect bad BISECT_HEAD &&
+ check_same BROKEN_HASH5 BISECT_HEAD &&
+ git bisect good BISECT_HEAD &&
+ check_same BROKEN_HASH6 bisect/bad &&
+ git bisect reset
+'
+
+test_expect_success 'bisect: --no-checkout - target after breakage' '
+ git bisect reset &&
+ git bisect start broken BROKEN_HASH4 --no-checkout &&
+ check_same BROKEN_HASH6 BISECT_HEAD &&
+ git bisect good BISECT_HEAD &&
+ check_same BROKEN_HASH8 BISECT_HEAD &&
+ git bisect good BISECT_HEAD &&
+ check_same BROKEN_HASH9 bisect/bad &&
+ git bisect reset
+'
+
+test_expect_success 'bisect: demonstrate identification of damage boundary' "
+ git bisect reset &&
+ git checkout broken &&
+ git bisect start broken master --no-checkout &&
+ git bisect run eval '
+rc=1;
+if git rev-list --objects BISECT_HEAD >tmp.$$; then
+ git pack-objects --stdout >/dev/null < tmp.$$ && rc=0;
+fi;
+rm tmp.$$;
+test \$rc -eq 0;' &&
+ check_same BROKEN_HASH6 bisect/bad &&
+ git bisect reset
+"
+
test_done
--
1.7.6.352.gd542a2
^ permalink raw reply related
* [PATCH v15 4/7] bisect: introduce support for --no-checkout option.
From: Jon Seymour @ 2011-08-03 15:03 UTC (permalink / raw)
To: git; +Cc: chriscool, gitster, j6t, jnareb, Jon Seymour
In-Reply-To: <1312383811-7130-1-git-send-email-jon.seymour@gmail.com>
If --no-checkout is specified, then the bisection process uses:
git update-ref --no-deref HEAD <trial>
at each trial instead of:
git checkout <trial>
Improved-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
bisect.c | 33 ++++++++++++++++++++++-----------
bisect.h | 2 +-
builtin/bisect--helper.c | 7 +++++--
3 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/bisect.c b/bisect.c
index dd7e8ed..c7b7d79 100644
--- a/bisect.c
+++ b/bisect.c
@@ -24,6 +24,7 @@ struct argv_array {
static const char *argv_checkout[] = {"checkout", "-q", NULL, "--", NULL};
static const char *argv_show_branch[] = {"show-branch", NULL, NULL};
+static const char *argv_update_ref[] = {"update-ref", "--no-deref", "BISECT_HEAD", NULL, NULL};
/* bits #0-15 in revision.h */
@@ -707,16 +708,23 @@ static void mark_expected_rev(char *bisect_rev_hex)
die("closing file %s: %s", filename, strerror(errno));
}
-static int bisect_checkout(char *bisect_rev_hex)
+static int bisect_checkout(char *bisect_rev_hex, int no_checkout)
{
int res;
mark_expected_rev(bisect_rev_hex);
argv_checkout[2] = bisect_rev_hex;
- res = run_command_v_opt(argv_checkout, RUN_GIT_CMD);
- if (res)
- exit(res);
+ if (no_checkout) {
+ argv_update_ref[3] = bisect_rev_hex;
+ if (run_command_v_opt(argv_update_ref, RUN_GIT_CMD))
+ die("update-ref --no-deref HEAD failed on %s",
+ bisect_rev_hex);
+ } else {
+ res = run_command_v_opt(argv_checkout, RUN_GIT_CMD);
+ if (res)
+ exit(res);
+ }
argv_show_branch[1] = bisect_rev_hex;
return run_command_v_opt(argv_show_branch, RUN_GIT_CMD);
@@ -788,7 +796,7 @@ static void handle_skipped_merge_base(const unsigned char *mb)
* - If one is "skipped", we can't know but we should warn.
* - If we don't know, we should check it out and ask the user to test.
*/
-static void check_merge_bases(void)
+static void check_merge_bases(int no_checkout)
{
struct commit_list *result;
int rev_nr;
@@ -806,7 +814,7 @@ static void check_merge_bases(void)
handle_skipped_merge_base(mb);
} else {
printf("Bisecting: a merge base must be tested\n");
- exit(bisect_checkout(sha1_to_hex(mb)));
+ exit(bisect_checkout(sha1_to_hex(mb), no_checkout));
}
}
@@ -849,7 +857,7 @@ static int check_ancestors(const char *prefix)
* If a merge base must be tested by the user, its source code will be
* checked out to be tested by the user and we will exit.
*/
-static void check_good_are_ancestors_of_bad(const char *prefix)
+static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout)
{
const char *filename = git_path("BISECT_ANCESTORS_OK");
struct stat st;
@@ -868,7 +876,7 @@ static void check_good_are_ancestors_of_bad(const char *prefix)
/* Check if all good revs are ancestor of the bad rev. */
if (check_ancestors(prefix))
- check_merge_bases();
+ check_merge_bases(no_checkout);
/* Create file BISECT_ANCESTORS_OK. */
fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
@@ -908,8 +916,11 @@ static void show_diff_tree(const char *prefix, struct commit *commit)
* We use the convention that exiting with an exit code 10 means that
* the bisection process finished successfully.
* In this case the calling shell script should exit 0.
+ *
+ * If no_checkout is non-zero, the bisection process does not
+ * checkout the trial commit but instead simply updates BISECT_HEAD.
*/
-int bisect_next_all(const char *prefix)
+int bisect_next_all(const char *prefix, int no_checkout)
{
struct rev_info revs;
struct commit_list *tried;
@@ -920,7 +931,7 @@ int bisect_next_all(const char *prefix)
if (read_bisect_refs())
die("reading bisect refs failed");
- check_good_are_ancestors_of_bad(prefix);
+ check_good_are_ancestors_of_bad(prefix, no_checkout);
bisect_rev_setup(&revs, prefix, "%s", "^%s", 1);
revs.limited = 1;
@@ -966,6 +977,6 @@ int bisect_next_all(const char *prefix)
"(roughly %d step%s)\n", nr, (nr == 1 ? "" : "s"),
steps, (steps == 1 ? "" : "s"));
- return bisect_checkout(bisect_rev_hex);
+ return bisect_checkout(bisect_rev_hex, no_checkout);
}
diff --git a/bisect.h b/bisect.h
index 0862ce5..22f2e4d 100644
--- a/bisect.h
+++ b/bisect.h
@@ -27,7 +27,7 @@ struct rev_list_info {
const char *header_prefix;
};
-extern int bisect_next_all(const char *prefix);
+extern int bisect_next_all(const char *prefix, int no_checkout);
extern int estimate_bisect_steps(int all);
diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c
index 5b22639..8d325a5 100644
--- a/builtin/bisect--helper.c
+++ b/builtin/bisect--helper.c
@@ -4,16 +4,19 @@
#include "bisect.h"
static const char * const git_bisect_helper_usage[] = {
- "git bisect--helper --next-all",
+ "git bisect--helper --next-all [--no-checkout]",
NULL
};
int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
{
int next_all = 0;
+ int no_checkout = 0;
struct option options[] = {
OPT_BOOLEAN(0, "next-all", &next_all,
"perform 'git bisect next'"),
+ OPT_BOOLEAN(0, "no-checkout", &no_checkout,
+ "update BISECT_HEAD instead of checking out the current commit"),
OPT_END()
};
@@ -24,5 +27,5 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
usage_with_options(git_bisect_helper_usage, options);
/* next-all */
- return bisect_next_all(prefix);
+ return bisect_next_all(prefix, no_checkout);
}
--
1.7.6.352.gd542a2
^ permalink raw reply related
* [PATCH v15 3/7] bisect: add tests to document expected behaviour in presence of broken trees.
From: Jon Seymour @ 2011-08-03 15:03 UTC (permalink / raw)
To: git; +Cc: chriscool, gitster, j6t, jnareb, Jon Seymour
In-Reply-To: <1312383811-7130-1-git-send-email-jon.seymour@gmail.com>
If the repo is broken, we expect bisect to fail.
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
t/t6030-bisect-porcelain.sh | 48 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index b3d1b14..9ae2de8 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -581,5 +581,53 @@ test_expect_success 'erroring out when using bad path parameters' '
'
#
+# This creates a broken branch which cannot be checked out because
+# the tree created has been deleted.
#
+# H1-H2-H3-H4-H5-H6-H7 <--other
+# \
+# S5-S6'-S7'-S8'-S9 <--broken
+#
+# Commits marked with ' have a missing tree.
+#
+test_expect_success 'broken branch creation' '
+ git bisect reset &&
+ git checkout -b broken $HASH4 &&
+ git tag BROKEN_HASH4 $HASH4 &&
+ add_line_into_file "5(broken): first line on a broken branch" hello2 &&
+ git tag BROKEN_HASH5 &&
+ mkdir missing &&
+ :> missing/MISSING &&
+ git add missing/MISSING &&
+ git commit -m "6(broken): Added file that will be deleted"
+ git tag BROKEN_HASH6 &&
+ add_line_into_file "7(broken): second line on a broken branch" hello2 &&
+ git tag BROKEN_HASH7 &&
+ add_line_into_file "8(broken): third line on a broken branch" hello2 &&
+ git tag BROKEN_HASH8 &&
+ git rm missing/MISSING &&
+ git commit -m "9(broken): Remove missing file"
+ git tag BROKEN_HASH9 &&
+ rm .git/objects/39/f7e61a724187ab767d2e08442d9b6b9dab587d
+'
+
+echo "" > expected.ok
+cat > expected.missing-tree.default <<EOF
+fatal: unable to read tree 39f7e61a724187ab767d2e08442d9b6b9dab587d
+EOF
+
+test_expect_success 'bisect fails if tree is broken on start commit' '
+ git bisect reset &&
+ test_must_fail git bisect start BROKEN_HASH7 BROKEN_HASH4 2>error.txt &&
+ test_cmp expected.missing-tree.default error.txt
+'
+
+test_expect_success 'bisect fails if tree is broken on trial commit' '
+ git bisect reset &&
+ test_must_fail git bisect start BROKEN_HASH9 BROKEN_HASH4 2>error.txt &&
+ git reset --hard broken &&
+ git checkout broken &&
+ test_cmp expected.missing-tree.default error.txt
+'
+
test_done
--
1.7.6.352.gd542a2
^ permalink raw reply related
* [PATCH v15 1/7] bisect: move argument parsing before state modification.
From: Jon Seymour @ 2011-08-03 15:03 UTC (permalink / raw)
To: git; +Cc: chriscool, gitster, j6t, jnareb, Jon Seymour
In-Reply-To: <1312383811-7130-1-git-send-email-jon.seymour@gmail.com>
Currently 'git bisect start' modifies some state prior to checking
that its arguments are valid.
This change moves argument validation before state modification
with the effect that state modification does not occur
unless argument validations succeeds.
An existing test is changed to check that new bisect state
is not created if arguments are invalid.
A new test is added to check that existing bisect state
is not modified if arguments are invalid.
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
git-bisect.sh | 66 +++++++++++++++++++++---------------------
t/t6030-bisect-porcelain.sh | 14 +++++++--
2 files changed, 44 insertions(+), 36 deletions(-)
diff --git a/git-bisect.sh b/git-bisect.sh
index b2186a8..20f6dd5 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -60,6 +60,39 @@ bisect_autostart() {
bisect_start() {
#
+ # Check for one bad and then some good revisions.
+ #
+ has_double_dash=0
+ for arg; do
+ case "$arg" in --) has_double_dash=1; break ;; esac
+ done
+ orig_args=$(git rev-parse --sq-quote "$@")
+ bad_seen=0
+ eval=''
+ while [ $# -gt 0 ]; do
+ arg="$1"
+ case "$arg" in
+ --)
+ shift
+ break
+ ;;
+ *)
+ rev=$(git rev-parse -q --verify "$arg^{commit}") || {
+ test $has_double_dash -eq 1 &&
+ die "$(eval_gettext "'\$arg' does not appear to be a valid revision")"
+ break
+ }
+ case $bad_seen in
+ 0) state='bad' ; bad_seen=1 ;;
+ *) state='good' ;;
+ esac
+ eval="$eval bisect_write '$state' '$rev' 'nolog'; "
+ shift
+ ;;
+ esac
+ done
+
+ #
# Verify HEAD.
#
head=$(GIT_DIR="$GIT_DIR" git symbolic-ref -q HEAD) ||
@@ -98,39 +131,6 @@ bisect_start() {
bisect_clean_state || exit
#
- # Check for one bad and then some good revisions.
- #
- has_double_dash=0
- for arg; do
- case "$arg" in --) has_double_dash=1; break ;; esac
- done
- orig_args=$(git rev-parse --sq-quote "$@")
- bad_seen=0
- eval=''
- while [ $# -gt 0 ]; do
- arg="$1"
- case "$arg" in
- --)
- shift
- break
- ;;
- *)
- rev=$(git rev-parse -q --verify "$arg^{commit}") || {
- test $has_double_dash -eq 1 &&
- die "$(eval_gettext "'\$arg' does not appear to be a valid revision")"
- break
- }
- case $bad_seen in
- 0) state='bad' ; bad_seen=1 ;;
- *) state='good' ;;
- esac
- eval="$eval bisect_write '$state' '$rev' 'nolog'; "
- shift
- ;;
- esac
- done
-
- #
# Change state.
# In case of mistaken revs or checkout error, or signals received,
# "bisect_auto_next" below may exit or misbehave.
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index b5063b6..b3d1b14 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -138,15 +138,23 @@ test_expect_success 'bisect start: back in good branch' '
grep "* other" branch.output > /dev/null
'
-test_expect_success 'bisect start: no ".git/BISECT_START" if junk rev' '
- git bisect start $HASH4 $HASH1 -- &&
- git bisect good &&
+test_expect_success 'bisect start: no ".git/BISECT_START" created if junk rev' '
+ git bisect reset &&
test_must_fail git bisect start $HASH4 foo -- &&
git branch > branch.output &&
grep "* other" branch.output > /dev/null &&
test_must_fail test -e .git/BISECT_START
'
+test_expect_success 'bisect start: existing ".git/BISECT_START" not modified if junk rev' '
+ git bisect start $HASH4 $HASH1 -- &&
+ git bisect good &&
+ cp .git/BISECT_START saved &&
+ test_must_fail git bisect start $HASH4 foo -- &&
+ git branch > branch.output &&
+ grep "* (no branch)" branch.output > /dev/null &&
+ test_cmp saved .git/BISECT_START
+'
test_expect_success 'bisect start: no ".git/BISECT_START" if mistaken rev' '
git bisect start $HASH4 $HASH1 -- &&
git bisect good &&
--
1.7.6.352.gd542a2
^ permalink raw reply related
* [PATCH v15 2/7] bisect: use && to connect statements that are deferred with eval.
From: Jon Seymour @ 2011-08-03 15:03 UTC (permalink / raw)
To: git; +Cc: chriscool, gitster, j6t, jnareb, Jon Seymour
In-Reply-To: <1312383811-7130-1-git-send-email-jon.seymour@gmail.com>
Christian Couder pointed out that the existing eval strategy
swallows an initial non-zero return. Using && to connect
the statements should fix this.
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
git-bisect.sh | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/git-bisect.sh b/git-bisect.sh
index 20f6dd5..a44ffe1 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -86,7 +86,7 @@ bisect_start() {
0) state='bad' ; bad_seen=1 ;;
*) state='good' ;;
esac
- eval="$eval bisect_write '$state' '$rev' 'nolog'; "
+ eval="$eval bisect_write '$state' '$rev' 'nolog' &&"
shift
;;
esac
@@ -145,7 +145,7 @@ bisect_start() {
#
echo "$start_head" >"$GIT_DIR/BISECT_START" &&
git rev-parse --sq-quote "$@" >"$GIT_DIR/BISECT_NAMES" &&
- eval "$eval" &&
+ eval "$eval true" &&
echo "git bisect start$orig_args" >>"$GIT_DIR/BISECT_LOG" || exit
#
# Check if we can proceed to the next bisect state.
--
1.7.6.352.gd542a2
^ permalink raw reply related
* [PATCH v15 0/7] bisect: Add support for --no-checkout option
From: Jon Seymour @ 2011-08-03 15:03 UTC (permalink / raw)
To: git; +Cc: chriscool, gitster, j6t, jnareb, Jon Seymour
Motivation
==========
For some bisection tasks, checking out the commit at each stage of the bisection process is unecessary or undesirable.
This series adds support for a --no-checkout option to git-bisect.
If specified on a start command, --no-checkout causes 'git bisect' to update BISECT_HEAD at each stage of the bisection process instead of checking out the commit at that point.
One application of the --no-checkout option is to find, within a partially damaged repository, a commit that has at least one parent whose graph is fully reachable in the sense of 'git pack-objects'.
For example:
git bisect start BISECT_HEAD <some-known-good-commit> <boundary-commits> --no-checkout
git bisect run eval '
rc=1;
if git rev-list --objects BISECT_HEAD >tmp.$$; then
git pack-objects --stdout >/dev/null < tmp.$$ && rc=0;
fi;
rm tmp.$$;
test $rc -eq 0;'
<some-known-good-commit> is a known good commit, for which the test passes.
<boundary-commits> are commits chosen to prevent the bisection visiting missing or corrupt commit objects.
Assuming this git bisect run completes successfully, bisect/bad will refer to a commit which has at least one parent that is fully reachable in the sense of 'git pack-objects'.
Patch Synopsis
==============
Remediation
-----------
Patch 1/7 changes existing behaviour in the case that an invalid revision argument is supplied to 'git bisect start'. In particular, in this case, bisection state is neither created or modified if argument validation fails. Previously, existing bisection state would be cleared even if the revision arguments were subsequently determined to be invalid.
Patch 2/7 remediates a potential flaw that might hide a failure in a chain of pasted statements.
Patch 3/7 adds a test which documents the existing behaviour of git bisect in the presence of tree damage.
New Function
------------
Patch 4/7 modifies the C code that supports bisection.
Patch 5/7 modifies porcelain to enable option exposed by 4/7.
Patch 6/7 adds some tests.
Patch 7/7 adds some documentation.
Revision History
----------------
v15:
Fixed reset behaviour in --no-checkout case. Added one test for same.
Simplified implementation so that no-checkout mode is inferred by presence of
$GIT_DIR/BISECT_HEAD eliminating the need for a separate BISECT_MODE control file.
Patch 8/8 from v13/14 was redistributed and squashed into earlier commits.
Style and documentation edits based on feedback from Christian Coulder.
v14:
Reverted --bisect-mode aspect of v13 change so C code matches v11.
v13:
Following suggestions from Junio:
* Replaced BISECT_NO_CHECKOUT control file with BISECT_MODE.
* Changed name of internal option on bisect--helper from --no-checkout to --bisect-mode=checkout|update-ref.
* Changed --no-checkout bisections to update BISECT_HEAD instead of HEAD.
v11:
Removed support for --update-ref=<ref>, per Junio's preference.
v10:
Changed the way deferred statements are connected. Reverted some whitespace minimization.
v8:
Further feedback from Christian Couder. Support --update-ref <ref>.
v6:
This series includes numerous improvements suggested by Christian Couder.
Reworks:
"bisect: allow git bisect to be used with repos containing damaged trees."
Replaced --ignore-checkout-failure with --no-checkout option suggested by Junio.
Todo
-----
* Implement full support for bisection in bare repositories.
Jon Seymour (7):
bisect: move argument parsing before state modification.
bisect: use && to connect statements that are deferred with eval.
bisect: add tests to document expected behaviour in presence of
broken trees.
bisect: introduce support for --no-checkout option.
bisect: introduce --no-checkout support into porcelain.
bisect: add tests for the --no-checkout option.
bisect: add documentation for --no-checkout option.
Documentation/git-bisect.txt | 32 +++++++++-
bisect.c | 33 +++++++---
bisect.h | 2 +-
builtin/bisect--helper.c | 7 ++-
git-bisect.sh | 110 +++++++++++++++++++-------------
t/t6030-bisect-porcelain.sh | 144 +++++++++++++++++++++++++++++++++++++++++-
6 files changed, 265 insertions(+), 63 deletions(-)
--
1.7.6.352.g5540e
^ 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