* Re: [ANNOUNCE/RFC] cj-git-patchtool: a "rebase -i" with more interaction
From: Christian Jaeger @ 2011-08-04 6:02 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <m3d3gmrchz.fsf@localhost.localdomain>
2011/8/3 Jakub Narebski <jnareb@gmail.com>:
> I have added cj-git-patchtool to "Patch-management Interface layers"
> section of "Interfaces, frontends and tools" page on Git Wiki:
Cool, thanks!
> I use one of patch management interfaces for that, namely StGit. It
> operates on stack of patches, which you can apply and unapply, going
> back and forth and correcting them.
I knew StGit existed, but I've never actually tried it. Now I also see
that the description of Guilt actually sounds exactly what
cj-git-patchtool does. (I was expecting that these tools would just
let me easily create sets of patches, similar to Darcs, not that
they'd actually allow to edit patches to fix conflicts.) I'll have to
try them out as soon as I find some time. Thanks for the hint.
Christian.
^ permalink raw reply
* Re: git-fast-export is returning streams with source code inside
From: Jeff King @ 2011-08-04 7:05 UTC (permalink / raw)
To: James Gregory; +Cc: git
In-Reply-To: <CAFC9htxwRg=+RD68hnnRy0hfptq23x3bL+xxHieK1evfFCTPjw@mail.gmail.com>
On Mon, Aug 01, 2011 at 12:57:58PM +0100, James Gregory wrote:
> I'm not sure if this is the right place to post bug reports - if not,
> please can you let me know.
This is the right place.
> I've found (what appears to be) a problem in git-fast-export. I've
> filed a bug in Launchpad, but I'm not sure if anyone from the Git
> community actively monitors it so I'm reporting it here to see if it
> can be fixed.
I don't think anybody monitors Launchpad explicitly; thanks for the
pointer.
> The bug can be viewed online at:
> https://bugs.launchpad.net/ubuntu/+source/git/+bug/815828
> and I've done my best to describe the bug in some detail. If you need
> me to elaborate on the problem further, don't hesitate to let me know.
Definitely looks like a bug. Is it possible for you to make the
offending repo available either publicly or to me in private? There's
not enough information in your report for me to reproduce the problem
here.
-Peff
^ permalink raw reply
* Re: What's cooking in git.git (Aug 2011, #01; Wed, 3)
From: Johannes Sixt @ 2011-08-04 7:19 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Elijah Newren
In-Reply-To: <7vzkjq6mpn.fsf@alter.siamese.dyndns.org>
Am 8/4/2011 2:32, schrieb Junio C Hamano:
> * en/merge-recursive (2011-07-14) 50 commits
> - fixup! Do not assume that qsort is stable
...
> - merge-recursive: Fix sorting order and directory change assumptions
...
> The tip one should be squashed somewhere.
I suggest this one.
> I wanted to push this out in
> 'next' today, but this seems to regress a rather trivial renaming merge,
> so I had to rewind and rebuild 'next' before pushing it out.
Also, make_room_for_path() walks the entire list of files to remove on
each invocation and calls unlink() on each of them, which fails after the
name was re-created as a directory. IIUC, this is O(N*M) behavior where N
is the number of files to remove and M is the number of directories to
create, and causes unnecessary system calls. (Well, this can be fixed when
the series is in next because it is not as critical as the regression that
you found.)
-- Hannes
^ permalink raw reply
* Re: [PATCH] Tolerate zlib deflation with window size < 32Kb
From: Roberto Tyley @ 2011-08-04 7:40 UTC (permalink / raw)
To: git
In-Reply-To: <CAFY1edZyO7oYDi+tV2mxbhBHY_cf2F0bD7+KF9rxmKYygSFAjA@mail.gmail.com>
On 4 August 2011 00:56, Junio C Hamano <gitster@pobox.com> wrote:
> roberto.tyley@gmail.com writes:
> > - if (map[0] == 0x78 && !(word % 31))
> > + if ((map[0] & 0x88) == 0x08 && !(word % 31))
>
> Are you sure about this 0x88? Isn't it 0x8F or something?
Ah- yes, you're right - the bitmask should be 0x8F, because the
lower nibble of a deflated zlib stream is 8 (8=deflate) and we want
to match all 4 bits.
Thankfully the rest of the logic still applies - I'll submit an
updated patch in a minute, once I've conquered my embarrassment :-)
^ permalink raw reply
* Re: [PATCH] Tolerate zlib deflation with window size < 32Kb
From: Sverre Rabbelier @ 2011-08-04 7:45 UTC (permalink / raw)
To: Roberto Tyley; +Cc: git
In-Reply-To: <CAFY1edZLAjVRs0LUx6CvD9i5aZu6kZ1ecJdUsvZgmtGkajOqow@mail.gmail.com>
Heya,
On Thu, Aug 4, 2011 at 09:40, Roberto Tyley <roberto.tyley@gmail.com> wrote:
> Thankfully the rest of the logic still applies - I'll submit an
> updated patch in a minute, once I've conquered my embarrassment :-)
Perhaps you can include a test to increase confidence that it works now? :)
--
Cheers,
Sverre Rabbelier
^ permalink raw reply
* Re: git-fast-export is returning streams with source code inside
From: James Gregory @ 2011-08-04 9:08 UTC (permalink / raw)
To: Jeff King; +Cc: git
In-Reply-To: <20110804070528.GA11805@sigill.intra.peff.net>
Hi Peff,
Thanks for your reply. I'm afraid I won't be able to allow you access
to repo as it is for a business project and covered by NDAs, etc. If I
can do anything to help with diagnosing the problem (debug logs, more
excerpts from the stream, etc.) then that shouldn't be a problem.
James
On 4 August 2011 08:05, Jeff King <peff@peff.net> wrote:
> On Mon, Aug 01, 2011 at 12:57:58PM +0100, James Gregory wrote:
>
>> I'm not sure if this is the right place to post bug reports - if not,
>> please can you let me know.
>
> This is the right place.
>
>> I've found (what appears to be) a problem in git-fast-export. I've
>> filed a bug in Launchpad, but I'm not sure if anyone from the Git
>> community actively monitors it so I'm reporting it here to see if it
>> can be fixed.
>
> I don't think anybody monitors Launchpad explicitly; thanks for the
> pointer.
>
>> The bug can be viewed online at:
>> https://bugs.launchpad.net/ubuntu/+source/git/+bug/815828
>> and I've done my best to describe the bug in some detail. If you need
>> me to elaborate on the problem further, don't hesitate to let me know.
>
> Definitely looks like a bug. Is it possible for you to make the
> offending repo available either publicly or to me in private? There's
> not enough information in your report for me to reproduce the problem
> here.
>
> -Peff
>
--
James Gregory
Senior Developer
epiGenesys - a University of Sheffield company
Enterprise Zone, Portobello, Sheffield, S1 4DP, UK
T: +44 (0)114 22 21 884 ~ F: +44 (0)114 22 24 042
www.epigenesys.co.uk ~ @epigenesys
--
This email and its attachments should be considered confidential and
are intended solely for the individual to whom the email is addressed.
If you are not the intended recipient you should take no action based
upon them, nor should you copy or show them to anyone. Any views or
opinions expressed are solely those of the author and might not
represent those of Epi Genesys Limited.
Epi Genesys Limited is registered in England and Wales with company
number 06388971 and has its registered office at 40 Leavygreave Road,
Sheffield, S3 7RD.
^ permalink raw reply
* Re: gitweb highligh generate illegal char when the content had utf-8 chars
From: Ramkumar Ramachandra @ 2011-08-04 9:11 UTC (permalink / raw)
To: zzs; +Cc: git, Jakub Narebski
In-Reply-To: <20110804053123.GA13198@greatfirst.com>
Hi,
zzs writes:
> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
> index dab89f2..48def38 100755
> --- a/gitweb/gitweb.perl
> +++ b/gitweb/gitweb.perl
> @@ -6465,7 +6465,7 @@ sub git_blob {
> $nr++;
> $line = untabify($line);
> printf qq!<div class="pre"><a id="l%i" href="%s#l%i" class="linenr">%4i</a> %s</div>\n!,
> - $nr, esc_attr(href(-replay => 1)), $nr, $nr, $syntax ? $line : esc_html($line, -nbsp=>1);
> + $nr, esc_attr(href(-replay => 1)), $nr, $nr, $syntax ? to_utf8($line) : esc_html($line, -nbsp=>1);
> }
> }
> close $fd
Looks sane, but I don't know enough about Gitweb to comment.
+CC: Jakub, who can probably say more.
Thanks.
-- Ram
^ permalink raw reply
* Re: [PATCH 17/18] revert: Introduce --continue to continue the operation
From: Ramkumar Ramachandra @ 2011-08-04 9:22 UTC (permalink / raw)
To: Christian Couder
Cc: Junio C Hamano, Git List, Jonathan Nieder, Daniel Barkalow,
Jeff King
In-Reply-To: <201108040657.24610.chriscool@tuxfamily.org>
Hi Christian,
Christian Couder writes:
> On Monday 01 August 2011 20:07:04 Ramkumar Ramachandra wrote:
>> +test_expect_success '--continue complains when there are unresolved
>> conflicts' '
>> + pristine_detach initial &&
>> + test_must_fail git cherry-pick base..picked &&
>> + test_must_fail git cherry-pick --continue
>> +'
>
> When I try to manually run the above test I get:
>
> -----------------------------------
>
> $ pristine_detach initial
> Warning: you are leaving 1 commit behind, not connected to
> any of your branches:
>
> 30b20f1 unrelatedpick
>
> HEAD is now at df2a63d... initial
> $
> $ git cherry-pick base..picked
> [detached HEAD 30b20f1] unrelatedpick
> Author: A U Thor <author@example.com>
> 1 files changed, 1 insertions(+), 1 deletions(-)
> Auto-merging foo
> CONFLICT (content): Merge conflict in foo
> error: could not apply fdc0b12... picked
> hint: after resolving the conflicts, mark the corrected paths
> hint: with 'git add <paths>' or 'git rm <paths>'
> hint: and commit the result with 'git commit'
> $
> $ git cherry-pick --continue
> fatal: No cherry-pick in progress
Good catch. It should be "base..anotherpick". Fixed now.
-- Ram
^ permalink raw reply
* Re: [PATCH 11/18] revert: Save command-line options for continuing operation
From: Ramkumar Ramachandra @ 2011-08-04 9:25 UTC (permalink / raw)
To: Christian Couder
Cc: Junio C Hamano, Git List, Jonathan Nieder, Daniel Barkalow,
Jeff King
In-Reply-To: <201108040605.46420.chriscool@tuxfamily.org>
Hi Christian,
Christian Couder writes:
> On Monday 01 August 2011 20:06:58 Ramkumar Ramachandra wrote:
>> +
>> +test_expect_success 'cherry-pick persists opts correctly' '
>> + rm -rf .git/sequencer &&
>> + pristine_detach initial &&
>
> pristine_detach() does a "rm -rf .git/sequencer" already.
Fixed.
> "&&" is missing at the end of the line.
[...]
Fixed all. Thanks.
-- Ram
^ permalink raw reply
* Re: [PATCH 09/18] revert: Don't create invalid replay_opts in parse_args
From: Ramkumar Ramachandra @ 2011-08-04 9:34 UTC (permalink / raw)
To: Christian Couder
Cc: Junio C Hamano, Git List, Jonathan Nieder, Daniel Barkalow,
Jeff King
In-Reply-To: <201108020841.41593.chriscool@tuxfamily.org>
Hi Christian,
Christian Couder writes:
> ... and we could remove the "set" variable like this:
>
> while ((this_opt = va_arg(ap, const char *))) {
> if (va_arg(ap, int))
> break;
> }
Very elegant- I especially like this.
You've reduced this to simply checking if the while loop ended
properly, or broke (using a break statement) by checking the
conditional that drove the loop.
Thanks.
-- Ram
^ permalink raw reply
* Re: gitweb highligh generate illegal char when the content had utf-8 chars
From: Jakub Narębski @ 2011-08-04 9:39 UTC (permalink / raw)
To: Ramkumar Ramachandra; +Cc: zzs, git
In-Reply-To: <CALkWK0kURz_Rax-JOPT2sW1x4VrqWk=KDjUzzw4apacDo1UTyg@mail.gmail.com>
On Thu, Aug 4, 2011 at 11:11 AM, Ramkumar Ramachandra
<artagnon@gmail.com> wrote:
> zzs writes:
>> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
>> index dab89f2..48def38 100755
>> --- a/gitweb/gitweb.perl
>> +++ b/gitweb/gitweb.perl
>> @@ -6465,7 +6465,7 @@ sub git_blob {
>> $nr++;
>> $line = untabify($line);
>> printf qq!<div class="pre"><a id="l%i" href="%s#l%i" class="linenr">%4i</a> %s</div>\n!,
>> - $nr, esc_attr(href(-replay => 1)), $nr, $nr, $syntax ? $line : esc_html($line, -nbsp=>1);
>> + $nr, esc_attr(href(-replay => 1)), $nr, $nr, $syntax ? to_utf8($line) : esc_html($line, -nbsp=>1);
>> }
>> }
>> close $fd
>
> Looks sane, but I don't know enough about Gitweb to comment.
> +CC: Jakub, who can probably say more.
This looks correct.
--
Jakub Narebski
^ permalink raw reply
* [PATCH] rebase -i: fix has_action
From: Noe Rubinstein @ 2011-08-04 9:39 UTC (permalink / raw)
To: git, gitster; +Cc: Noe Rubinstein
When doing git rebase -i, removing all actions in the todo list is
supposed to result in aborting the rebase. However, if there are spaces
at the beginning of an empty line, has_action returns true and the
rebase therefore removes all commits. This is probably not what a user
leaving a space on an empty line expects.
This patch fixes the bug by changing has_action to grep any line
containing anything that is not a space nor a #.
Signed-off-by: Noe Rubinstein <nrubinstein@proformatique.com>
---
git-rebase--interactive.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index c6ba7c1..bed79af 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -149,7 +149,7 @@ die_abort () {
}
has_action () {
- sane_grep '^[^#]' "$1" >/dev/null
+ sane_grep '^[^#[:space:]]' "$1" >/dev/null
}
# Run command with GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and
--
Noé Rubinstein
Avencall - XiVO IPBX OpenHardware
10 bis, rue Lucien VOILIN - 92800 Puteaux
Tél. : +33 (0)1 41 38 99 60 ext 123
Fax. : +33 (0)1 41 38 99 70
^ permalink raw reply related
* Re: [PATCH 17/18] revert: Introduce --continue to continue the operation
From: Ramkumar Ramachandra @ 2011-08-04 10:02 UTC (permalink / raw)
To: Christian Couder
Cc: Junio C Hamano, Git List, Jonathan Nieder, Daniel Barkalow,
Jeff King
In-Reply-To: <201108020451.36617.chriscool@tuxfamily.org>
Hi Christian,
Christian Couder writes:
> Ooops, sorry I mean like this:
>
> for (i = 1; *p; i++) {
> struct commit *commit = parse_insn_line(p, opts);
> if (!commit)
> return error(_("Could not parse line %d."), i);
> next = commit_list_append(commit, next);
> p = strchrnul(p, '\n');
> if (*p)
> p++;
> }
Thanks for catching this bug, and showing me how to handle it correctly! :)
While fixing this, I took the opportunity to incorporate all your
other suggestions in my new series. Will post the new series shortly.
[It broke my new series, but this was definitely worth fixing]
-- Ram
^ permalink raw reply
* Re: gitweb highligh generate illegal char when the content had utf-8 chars
From: Ramkumar Ramachandra @ 2011-08-04 10:05 UTC (permalink / raw)
To: zzs; +Cc: git, Jakub Narębski
In-Reply-To: <CANQwDwcR5sS3-m6SifQbjU1VoS5bxRRGJNZZj0U+zp=zsoGbLA@mail.gmail.com>
Hi,
Jakub Narębski writes:
> This looks correct.
Thanks Jakub.
>> zzs writes:
>>> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
>>> index dab89f2..48def38 100755
Please submit a nicely formatted patch with proper signoff so that we
can consider this for inclusion. Refer to
Documentation/SubmittingPatches for more details.
Thanks.
-- Ram
^ permalink raw reply
* [PATCH 00/18] Sequencer for inclusion v6
From: Ramkumar Ramachandra @ 2011-08-04 10:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: Git List, Jonathan Nieder, Christian Couder, Daniel Barkalow,
Jeff King
Hi,
Apart from the minor style changes, there are two big hilights in this
iteration of the series:
1. The "--continue complains when there are unresolved conflicts" test
is fixed. I'd written "base..picked" instead of "base..anotherpick"
earlier.
2. Special handling for the last line in the instruction sheet (when
it is not terminated by a newline). See [1] for an especially
convincing explanation from Junio.
All the changes made in this iteration are a direct result of
Christian's reviews -- a big thanks.
Thanks for reading.
-- Ram
[1]: http://mid.gmane.org/7v4o1ycsi4.fsf@alter.siamese.dyndns.org
Ramkumar Ramachandra (18):
advice: Introduce error_resolve_conflict
config: Introduce functions to write non-standard file
revert: Simplify and inline add_message_to_msg
revert: Don't check lone argument in get_encoding
revert: Rename no_replay to record_origin
revert: Eliminate global "commit" variable
revert: Introduce struct to keep command-line options
revert: Separate cmdline parsing from functional code
revert: Don't create invalid replay_opts in parse_args
revert: Save data for continuing after conflict resolution
revert: Save command-line options for continuing operation
revert: Make pick_commits functionally act on a commit list
revert: Introduce --reset to remove sequencer state
reset: Make reset remove the sequencer state
revert: Remove sequencer state when no commits are pending
revert: Don't implicitly stomp pending sequencer operation
revert: Introduce --continue to continue the operation
revert: Propagate errors upwards from do_pick_commit
Documentation/git-cherry-pick.txt | 6 +
Documentation/git-revert.txt | 6 +
Documentation/sequencer.txt | 9 +
Makefile | 2 +
advice.c | 31 ++-
advice.h | 3 +-
branch.c | 2 +
builtin/revert.c | 737 +++++++++++++++++++++++++++++--------
cache.h | 2 +
config.c | 36 ++-
sequencer.c | 19 +
sequencer.h | 20 +
t/7106-reset-sequence.sh | 44 +++
t/t3510-cherry-pick-sequence.sh | 214 +++++++++++
14 files changed, 960 insertions(+), 171 deletions(-)
create mode 100644 Documentation/sequencer.txt
create mode 100644 sequencer.c
create mode 100644 sequencer.h
create mode 100755 t/7106-reset-sequence.sh
create mode 100755 t/t3510-cherry-pick-sequence.sh
--
1.7.6.351.gb35ac.dirty
^ permalink raw reply
* [PATCH 02/18] config: Introduce functions to write non-standard file
From: Ramkumar Ramachandra @ 2011-08-04 10:39 UTC (permalink / raw)
To: Junio C Hamano
Cc: Git List, Jonathan Nieder, Christian Couder, Daniel Barkalow,
Jeff King
In-Reply-To: <1312454356-3070-1-git-send-email-artagnon@gmail.com>
Introduce two new functions corresponding to "git_config_set" and
"git_config_set_multivar" to write a non-standard configuration file.
Expose these new functions in cache.h for other git programs to use.
Helped-by: Jeff King <peff@peff.net>
Helped-by: Jonathan Nieder <jrnieder@gmail.com>
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
cache.h | 2 ++
config.c | 36 +++++++++++++++++++++++++++---------
2 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/cache.h b/cache.h
index 9e12d55..33d3428 100644
--- a/cache.h
+++ b/cache.h
@@ -1069,9 +1069,11 @@ extern int git_config_bool(const char *, const char *);
extern int git_config_maybe_bool(const char *, const char *);
extern int git_config_string(const char **, const char *, const char *);
extern int git_config_pathname(const char **, const char *, const char *);
+extern int git_config_set_in_file(const char *, const char *, const char *);
extern int git_config_set(const char *, const char *);
extern int git_config_parse_key(const char *, char **, int *);
extern int git_config_set_multivar(const char *, const char *, const char *, int);
+extern int git_config_set_multivar_in_file(const char *, const char *, const char *, const char *, int);
extern int git_config_rename_section(const char *, const char *);
extern const char *git_etc_gitconfig(void);
extern int check_repository_format_version(const char *var, const char *value, void *cb);
diff --git a/config.c b/config.c
index e42c59b..9e8580b 100644
--- a/config.c
+++ b/config.c
@@ -1092,6 +1092,12 @@ contline:
return offset;
}
+int git_config_set_in_file(const char *config_filename,
+ const char *key, const char *value)
+{
+ return git_config_set_multivar_in_file(config_filename, key, value, NULL, 0);
+}
+
int git_config_set(const char *key, const char *value)
{
return git_config_set_multivar(key, value, NULL, 0);
@@ -1189,19 +1195,14 @@ out_free_ret_1:
* - the config file is removed and the lock file rename()d to it.
*
*/
-int git_config_set_multivar(const char *key, const char *value,
- const char *value_regex, int multi_replace)
+int git_config_set_multivar_in_file(const char *config_filename,
+ const char *key, const char *value,
+ const char *value_regex, int multi_replace)
{
int fd = -1, in_fd;
int ret;
- char *config_filename;
struct lock_file *lock = NULL;
- if (config_exclusive_filename)
- config_filename = xstrdup(config_exclusive_filename);
- else
- config_filename = git_pathdup("config");
-
/* parse-key returns negative; flip the sign to feed exit(3) */
ret = 0 - git_config_parse_key(key, &store.key, &store.baselen);
if (ret)
@@ -1378,7 +1379,6 @@ int git_config_set_multivar(const char *key, const char *value,
out_free:
if (lock)
rollback_lock_file(lock);
- free(config_filename);
return ret;
write_err_out:
@@ -1387,6 +1387,24 @@ write_err_out:
}
+int git_config_set_multivar(const char *key, const char *value,
+ const char *value_regex, int multi_replace)
+{
+ const char *config_filename;
+ char *buf = NULL;
+ int ret;
+
+ if (config_exclusive_filename)
+ config_filename = config_exclusive_filename;
+ else
+ config_filename = buf = git_pathdup("config");
+
+ ret = git_config_set_multivar_in_file(config_filename, key, value,
+ value_regex, multi_replace);
+ free(buf);
+ return ret;
+}
+
static int section_name_match (const char *buf, const char *name)
{
int i = 0, j = 0, dot = 0;
--
1.7.6.351.gb35ac.dirty
^ permalink raw reply related
* [PATCH 01/18] advice: Introduce error_resolve_conflict
From: Ramkumar Ramachandra @ 2011-08-04 10:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: Git List, Jonathan Nieder, Christian Couder, Daniel Barkalow,
Jeff King
In-Reply-To: <1312454356-3070-1-git-send-email-artagnon@gmail.com>
Enable future callers to report a conflict and not die immediately by
introducing a new function called error_resolve_conflict.
Re-implement die_resolve_conflict as a call to error_resolve_conflict
followed by a call to die. Consequently, the message printed by
die_resolve_conflict changes from
fatal: 'commit' is not possible because you have unmerged files.
Please, fix them up in the work tree ...
...
to
error: 'commit' is not possible because you have unmerged files.
hint: Fix them up in the work tree ...
hint: ...
fatal: Exiting because of an unresolved conflict.
Hints are printed using the same advise function introduced in
v1.7.3-rc0~26^2~3 (Introduce advise() to print hints, 2010-08-11).
Inspired-by: Christian Couder <chistian.couder@gmail.com>
Helped-by: Jonathan Nieder <jrnieder@gmail.com>
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
advice.c | 31 ++++++++++++++++++++++++-------
advice.h | 3 ++-
builtin/revert.c | 9 ---------
3 files changed, 26 insertions(+), 17 deletions(-)
diff --git a/advice.c b/advice.c
index 0be4b5f..e02e632 100644
--- a/advice.c
+++ b/advice.c
@@ -19,6 +19,15 @@ static struct {
{ "detachedhead", &advice_detached_head },
};
+void advise(const char *advice, ...)
+{
+ va_list params;
+
+ va_start(params, advice);
+ vreportf("hint: ", advice, params);
+ va_end(params);
+}
+
int git_default_advice_config(const char *var, const char *value)
{
const char *k = skip_prefix(var, "advice.");
@@ -34,16 +43,24 @@ int git_default_advice_config(const char *var, const char *value)
return 0;
}
-void NORETURN die_resolve_conflict(const char *me)
+int error_resolve_conflict(const char *me)
{
- if (advice_resolve_conflict)
+ error("'%s' is not possible because you have unmerged files.", me);
+ if (advice_resolve_conflict) {
/*
* Message used both when 'git commit' fails and when
* other commands doing a merge do.
*/
- die("'%s' is not possible because you have unmerged files.\n"
- "Please, fix them up in the work tree, and then use 'git add/rm <file>' as\n"
- "appropriate to mark resolution and make a commit, or use 'git commit -a'.", me);
- else
- die("'%s' is not possible because you have unmerged files.", me);
+ advise("Fix them up in the work tree,");
+ advise("and then use 'git add/rm <file>' as");
+ advise("appropriate to mark resolution and make a commit,");
+ advise("or use 'git commit -a'.");
+ }
+ return -1;
+}
+
+void NORETURN die_resolve_conflict(const char *me)
+{
+ error_resolve_conflict(me);
+ die("Exiting because of an unresolved conflict.");
}
diff --git a/advice.h b/advice.h
index 3244ebb..e5d0af7 100644
--- a/advice.h
+++ b/advice.h
@@ -11,7 +11,8 @@ extern int advice_implicit_identity;
extern int advice_detached_head;
int git_default_advice_config(const char *var, const char *value);
-
+void advise(const char *advice, ...);
+int error_resolve_conflict(const char *me);
extern void NORETURN die_resolve_conflict(const char *me);
#endif /* ADVICE_H */
diff --git a/builtin/revert.c b/builtin/revert.c
index 1f27c63..2df3f3b 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -214,15 +214,6 @@ static void write_cherry_pick_head(void)
strbuf_release(&buf);
}
-static void advise(const char *advice, ...)
-{
- va_list params;
-
- va_start(params, advice);
- vreportf("hint: ", advice, params);
- va_end(params);
-}
-
static void print_advice(void)
{
char *msg = getenv("GIT_CHERRY_PICK_HELP");
--
1.7.6.351.gb35ac.dirty
^ permalink raw reply related
* [PATCH 03/18] revert: Simplify and inline add_message_to_msg
From: Ramkumar Ramachandra @ 2011-08-04 10:39 UTC (permalink / raw)
To: Junio C Hamano
Cc: Git List, Jonathan Nieder, Christian Couder, Daniel Barkalow,
Jeff King
In-Reply-To: <1312454356-3070-1-git-send-email-artagnon@gmail.com>
The add_message_to_msg function has some dead code, an unclear API,
only one callsite. While it originally intended fill up an empty
commit message with the commit object name while picking, it really
doesn't do this -- a bug introduced in v1.5.1-rc1~65^2~2 (Make
git-revert & git-cherry-pick a builtin, 2007-03-01). Today, tests in
t3505-cherry-pick-empty.sh indicate that not filling up an empty
commit message is the desired behavior. Re-implement and inline the
function accordingly, with a beneficial side-effect: don't dereference
a NULL pointer when the commit doesn't have a delimeter after the
header.
Helped-by: Junio C Hamano <gitster@pobox.com>
Mentored-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
builtin/revert.c | 28 ++++++++++++++--------------
1 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/builtin/revert.c b/builtin/revert.c
index 2df3f3b..7dfe295 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -185,19 +185,6 @@ static char *get_encoding(const char *message)
return NULL;
}
-static void add_message_to_msg(struct strbuf *msgbuf, const char *message)
-{
- const char *p = message;
- while (*p && (*p != '\n' || p[1] != '\n'))
- p++;
-
- if (!*p)
- strbuf_addstr(msgbuf, sha1_to_hex(commit->object.sha1));
-
- p += 2;
- strbuf_addstr(msgbuf, p);
-}
-
static void write_cherry_pick_head(void)
{
int fd;
@@ -462,11 +449,24 @@ static int do_pick_commit(void)
}
strbuf_addstr(&msgbuf, ".\n");
} else {
+ const char *p;
+
base = parent;
base_label = msg.parent_label;
next = commit;
next_label = msg.label;
- add_message_to_msg(&msgbuf, msg.message);
+
+ /*
+ * Append the commit log message to msgbuf; it starts
+ * after the tree, parent, author, committer
+ * information followed by "\n\n".
+ */
+ p = strstr(msg.message, "\n\n");
+ if (p) {
+ p += 2;
+ strbuf_addstr(&msgbuf, p);
+ }
+
if (no_replay) {
strbuf_addstr(&msgbuf, "(cherry picked from commit ");
strbuf_addstr(&msgbuf, sha1_to_hex(commit->object.sha1));
--
1.7.6.351.gb35ac.dirty
^ permalink raw reply related
* [PATCH 04/18] revert: Don't check lone argument in get_encoding
From: Ramkumar Ramachandra @ 2011-08-04 10:39 UTC (permalink / raw)
To: Junio C Hamano
Cc: Git List, Jonathan Nieder, Christian Couder, Daniel Barkalow,
Jeff King
In-Reply-To: <1312454356-3070-1-git-send-email-artagnon@gmail.com>
The only place get_encoding uses the global "commit" variable is when
writing an error message explaining that its lone argument was NULL.
Since the function's only caller ensures that a NULL argument isn't
passed, we can remove this check with two beneficial consequences:
1. Since the function doesn't use the global "commit" variable any
more, it won't need to change when we eliminate the global variable
later in the series.
2. Translators no longer need to localize an error message that will
never be shown.
Suggested-by: Junio C Hamano <gitster@pobox.com>
Mentored-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
builtin/revert.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/builtin/revert.c b/builtin/revert.c
index 7dfe295..30b39c0 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -167,9 +167,6 @@ static char *get_encoding(const char *message)
{
const char *p = message, *eol;
- if (!p)
- die (_("Could not read commit message of %s"),
- sha1_to_hex(commit->object.sha1));
while (*p && *p != '\n') {
for (eol = p + 1; *eol && *eol != '\n'; eol++)
; /* do nothing */
--
1.7.6.351.gb35ac.dirty
^ permalink raw reply related
* [PATCH 05/18] revert: Rename no_replay to record_origin
From: Ramkumar Ramachandra @ 2011-08-04 10:39 UTC (permalink / raw)
To: Junio C Hamano
Cc: Git List, Jonathan Nieder, Christian Couder, Daniel Barkalow,
Jeff King
In-Reply-To: <1312454356-3070-1-git-send-email-artagnon@gmail.com>
The "-x" command-line option is used to record the name of the
original commits being picked in the commit message. The variable
corresponding to this option is named "no_replay" for historical
reasons; the name is especially confusing because the term "replay" is
used to describe what cherry-pick does (for example, in the
documentation of the "--mainline" option). So, give the variable
corresponding to the "-x" command-line option a better name:
"record_origin".
Mentored-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
builtin/revert.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/builtin/revert.c b/builtin/revert.c
index 30b39c0..794c050 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -35,7 +35,7 @@ static const char * const cherry_pick_usage[] = {
NULL
};
-static int edit, no_replay, no_commit, mainline, signoff, allow_ff;
+static int edit, record_origin, no_commit, mainline, signoff, allow_ff;
static enum { REVERT, CHERRY_PICK } action;
static struct commit *commit;
static int commit_argc;
@@ -91,7 +91,7 @@ static void parse_args(int argc, const char **argv)
if (action == CHERRY_PICK) {
struct option cp_extra[] = {
- OPT_BOOLEAN('x', NULL, &no_replay, "append commit name"),
+ OPT_BOOLEAN('x', NULL, &record_origin, "append commit name"),
OPT_BOOLEAN(0, "ff", &allow_ff, "allow fast-forward"),
OPT_END(),
};
@@ -464,7 +464,7 @@ static int do_pick_commit(void)
strbuf_addstr(&msgbuf, p);
}
- if (no_replay) {
+ if (record_origin) {
strbuf_addstr(&msgbuf, "(cherry picked from commit ");
strbuf_addstr(&msgbuf, sha1_to_hex(commit->object.sha1));
strbuf_addstr(&msgbuf, ")\n");
@@ -559,7 +559,7 @@ static int revert_or_cherry_pick(int argc, const char **argv)
die(_("cherry-pick --ff cannot be used with --signoff"));
if (no_commit)
die(_("cherry-pick --ff cannot be used with --no-commit"));
- if (no_replay)
+ if (record_origin)
die(_("cherry-pick --ff cannot be used with -x"));
if (edit)
die(_("cherry-pick --ff cannot be used with --edit"));
--
1.7.6.351.gb35ac.dirty
^ permalink raw reply related
* [PATCH 06/18] revert: Eliminate global "commit" variable
From: Ramkumar Ramachandra @ 2011-08-04 10:39 UTC (permalink / raw)
To: Junio C Hamano
Cc: Git List, Jonathan Nieder, Christian Couder, Daniel Barkalow,
Jeff King
In-Reply-To: <1312454356-3070-1-git-send-email-artagnon@gmail.com>
Functions which act on commits currently rely on a file-scope static
variable to be set before they're called. Consequently, the API and
corresponding callsites are ugly and unclear. Remove this variable
and change their API to accept the commit to act on as additional
argument so that the callsites change from looking like
commit = prepare_a_commit();
act_on_commit();
to looking like
commit = prepare_a_commit();
act_on_commit(commit);
This change is also in line with our long-term goal of exposing some
of these functions through a public API.
Inspired-by: Christian Couder <chriscool@tuxfamily.org>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
builtin/revert.c | 22 +++++++++++-----------
1 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/builtin/revert.c b/builtin/revert.c
index 794c050..d6c9f1d 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -37,7 +37,6 @@ static const char * const cherry_pick_usage[] = {
static int edit, record_origin, no_commit, mainline, signoff, allow_ff;
static enum { REVERT, CHERRY_PICK } action;
-static struct commit *commit;
static int commit_argc;
static const char **commit_argv;
static int allow_rerere_auto;
@@ -116,25 +115,25 @@ struct commit_message {
const char *message;
};
-static int get_message(const char *raw_message, struct commit_message *out)
+static int get_message(struct commit *commit, struct commit_message *out)
{
const char *encoding;
const char *abbrev, *subject;
int abbrev_len, subject_len;
char *q;
- if (!raw_message)
+ if (!commit->buffer)
return -1;
- encoding = get_encoding(raw_message);
+ encoding = get_encoding(commit->buffer);
if (!encoding)
encoding = "UTF-8";
if (!git_commit_encoding)
git_commit_encoding = "UTF-8";
out->reencoded_message = NULL;
- out->message = raw_message;
+ out->message = commit->buffer;
if (strcmp(encoding, git_commit_encoding))
- out->reencoded_message = reencode_string(raw_message,
+ out->reencoded_message = reencode_string(commit->buffer,
git_commit_encoding, encoding);
if (out->reencoded_message)
out->message = out->reencoded_message;
@@ -182,7 +181,7 @@ static char *get_encoding(const char *message)
return NULL;
}
-static void write_cherry_pick_head(void)
+static void write_cherry_pick_head(struct commit *commit)
{
int fd;
struct strbuf buf = STRBUF_INIT;
@@ -355,7 +354,7 @@ static int run_git_commit(const char *defmsg)
return run_command_v_opt(args, RUN_GIT_CMD);
}
-static int do_pick_commit(void)
+static int do_pick_commit(struct commit *commit)
{
unsigned char head[20];
struct commit *base, *next, *parent;
@@ -417,7 +416,7 @@ static int do_pick_commit(void)
die(_("%s: cannot parse parent commit %s"),
me, sha1_to_hex(parent->object.sha1));
- if (get_message(commit->buffer, &msg) != 0)
+ if (get_message(commit, &msg) != 0)
die(_("Cannot get commit message for %s"),
sha1_to_hex(commit->object.sha1));
@@ -470,7 +469,7 @@ static int do_pick_commit(void)
strbuf_addstr(&msgbuf, ")\n");
}
if (!no_commit)
- write_cherry_pick_head();
+ write_cherry_pick_head(commit);
}
if (!strategy || !strcmp(strategy, "recursive") || action == REVERT) {
@@ -548,6 +547,7 @@ static void read_and_refresh_cache(const char *me)
static int revert_or_cherry_pick(int argc, const char **argv)
{
struct rev_info revs;
+ struct commit *commit;
git_config(git_default_config, NULL);
me = action == REVERT ? "revert" : "cherry-pick";
@@ -570,7 +570,7 @@ static int revert_or_cherry_pick(int argc, const char **argv)
prepare_revs(&revs);
while ((commit = get_revision(&revs))) {
- int res = do_pick_commit();
+ int res = do_pick_commit(commit);
if (res)
return res;
}
--
1.7.6.351.gb35ac.dirty
^ permalink raw reply related
* [PATCH 07/18] revert: Introduce struct to keep command-line options
From: Ramkumar Ramachandra @ 2011-08-04 10:39 UTC (permalink / raw)
To: Junio C Hamano
Cc: Git List, Jonathan Nieder, Christian Couder, Daniel Barkalow,
Jeff King
In-Reply-To: <1312454356-3070-1-git-send-email-artagnon@gmail.com>
The current code uses a set of file-scope static variables to tell the
cherry-pick/ revert machinery how to replay the changes, and
initializes them by parsing the command-line arguments. In later
steps in this series, we would like to introduce an API function that
calls into this machinery directly and have a way to tell it what to
do. Hence, introduce a structure to group these variables, so that
the API can take them as a single replay_options parameter. The only
exception is the variable "me" -- remove it since it not an
independent option, and can be inferred from the action.
Unfortunately, this patch introduces a minor regression. Parsing
strategy-option violates a C89 rule: Initializers cannot refer to
variables whose address is not known at compile time. Currently, this
rule is violated by some other parts of Git as well, and it is
possible to get GCC to report these instances using the "-std=c89
-pedantic" option.
Inspired-by: Christian Couder <chriscool@tuxfamily.org>
Mentored-by: Jonathan Nieder <jrnieder@gmail.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
builtin/revert.c | 201 ++++++++++++++++++++++++++++++------------------------
1 files changed, 113 insertions(+), 88 deletions(-)
diff --git a/builtin/revert.c b/builtin/revert.c
index d6c9f1d..50f72de 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -35,76 +35,94 @@ static const char * const cherry_pick_usage[] = {
NULL
};
-static int edit, record_origin, no_commit, mainline, signoff, allow_ff;
-static enum { REVERT, CHERRY_PICK } action;
-static int commit_argc;
-static const char **commit_argv;
-static int allow_rerere_auto;
-
-static const char *me;
-
-/* Merge strategy. */
-static const char *strategy;
-static const char **xopts;
-static size_t xopts_nr, xopts_alloc;
+enum replay_action { REVERT, CHERRY_PICK };
+
+struct replay_opts {
+ enum replay_action action;
+
+ /* Boolean options */
+ int edit;
+ int record_origin;
+ int no_commit;
+ int signoff;
+ int allow_ff;
+ int allow_rerere_auto;
+
+ int mainline;
+ int commit_argc;
+ const char **commit_argv;
+
+ /* Merge strategy */
+ const char *strategy;
+ const char **xopts;
+ size_t xopts_nr, xopts_alloc;
+};
#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
+static const char *action_name(const struct replay_opts *opts)
+{
+ return opts->action == REVERT ? "revert" : "cherry-pick";
+}
+
static char *get_encoding(const char *message);
-static const char * const *revert_or_cherry_pick_usage(void)
+static const char * const *revert_or_cherry_pick_usage(struct replay_opts *opts)
{
- return action == REVERT ? revert_usage : cherry_pick_usage;
+ return opts->action == REVERT ? revert_usage : cherry_pick_usage;
}
static int option_parse_x(const struct option *opt,
const char *arg, int unset)
{
+ struct replay_opts **opts_ptr = opt->value;
+ struct replay_opts *opts = *opts_ptr;
+
if (unset)
return 0;
- ALLOC_GROW(xopts, xopts_nr + 1, xopts_alloc);
- xopts[xopts_nr++] = xstrdup(arg);
+ ALLOC_GROW(opts->xopts, opts->xopts_nr + 1, opts->xopts_alloc);
+ opts->xopts[opts->xopts_nr++] = xstrdup(arg);
return 0;
}
-static void parse_args(int argc, const char **argv)
+static void parse_args(int argc, const char **argv, struct replay_opts *opts)
{
- const char * const * usage_str = revert_or_cherry_pick_usage();
+ const char * const * usage_str = revert_or_cherry_pick_usage(opts);
int noop;
struct option options[] = {
- OPT_BOOLEAN('n', "no-commit", &no_commit, "don't automatically commit"),
- OPT_BOOLEAN('e', "edit", &edit, "edit the commit message"),
+ OPT_BOOLEAN('n', "no-commit", &opts->no_commit, "don't automatically commit"),
+ OPT_BOOLEAN('e', "edit", &opts->edit, "edit the commit message"),
{ OPTION_BOOLEAN, 'r', NULL, &noop, NULL, "no-op (backward compatibility)",
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 0 },
- OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
- OPT_INTEGER('m', "mainline", &mainline, "parent number"),
- OPT_RERERE_AUTOUPDATE(&allow_rerere_auto),
- OPT_STRING(0, "strategy", &strategy, "strategy", "merge strategy"),
- OPT_CALLBACK('X', "strategy-option", &xopts, "option",
+ OPT_BOOLEAN('s', "signoff", &opts->signoff, "add Signed-off-by:"),
+ OPT_INTEGER('m', "mainline", &opts->mainline, "parent number"),
+ OPT_RERERE_AUTOUPDATE(&opts->allow_rerere_auto),
+ OPT_STRING(0, "strategy", &opts->strategy, "strategy", "merge strategy"),
+ OPT_CALLBACK('X', "strategy-option", &opts, "option",
"option for merge strategy", option_parse_x),
OPT_END(),
OPT_END(),
OPT_END(),
};
- if (action == CHERRY_PICK) {
+ if (opts->action == CHERRY_PICK) {
struct option cp_extra[] = {
- OPT_BOOLEAN('x', NULL, &record_origin, "append commit name"),
- OPT_BOOLEAN(0, "ff", &allow_ff, "allow fast-forward"),
+ OPT_BOOLEAN('x', NULL, &opts->record_origin, "append commit name"),
+ OPT_BOOLEAN(0, "ff", &opts->allow_ff, "allow fast-forward"),
OPT_END(),
};
if (parse_options_concat(options, ARRAY_SIZE(options), cp_extra))
die(_("program error"));
}
- commit_argc = parse_options(argc, argv, NULL, options, usage_str,
- PARSE_OPT_KEEP_ARGV0 |
- PARSE_OPT_KEEP_UNKNOWN);
- if (commit_argc < 2)
+ opts->commit_argc = parse_options(argc, argv, NULL, options, usage_str,
+ PARSE_OPT_KEEP_ARGV0 |
+ PARSE_OPT_KEEP_UNKNOWN);
+ if (opts->commit_argc < 2)
usage_with_options(usage_str, options);
- commit_argv = argv;
+ opts->commit_argv = argv;
}
struct commit_message {
@@ -240,20 +258,20 @@ static struct tree *empty_tree(void)
return tree;
}
-static NORETURN void die_dirty_index(const char *me)
+static NORETURN void die_dirty_index(struct replay_opts *opts)
{
if (read_cache_unmerged()) {
- die_resolve_conflict(me);
+ die_resolve_conflict(action_name(opts));
} else {
if (advice_commit_before_merge) {
- if (action == REVERT)
+ if (opts->action == REVERT)
die(_("Your local changes would be overwritten by revert.\n"
"Please, commit your changes or stash them to proceed."));
else
die(_("Your local changes would be overwritten by cherry-pick.\n"
"Please, commit your changes or stash them to proceed."));
} else {
- if (action == REVERT)
+ if (opts->action == REVERT)
die(_("Your local changes would be overwritten by revert.\n"));
else
die(_("Your local changes would be overwritten by cherry-pick.\n"));
@@ -274,7 +292,8 @@ static int fast_forward_to(const unsigned char *to, const unsigned char *from)
static int do_recursive_merge(struct commit *base, struct commit *next,
const char *base_label, const char *next_label,
- unsigned char *head, struct strbuf *msgbuf)
+ unsigned char *head, struct strbuf *msgbuf,
+ struct replay_opts *opts)
{
struct merge_options o;
struct tree *result, *next_tree, *base_tree, *head_tree;
@@ -295,7 +314,7 @@ static int do_recursive_merge(struct commit *base, struct commit *next,
next_tree = next ? next->tree : empty_tree();
base_tree = base ? base->tree : empty_tree();
- for (xopt = xopts; xopt != xopts + xopts_nr; xopt++)
+ for (xopt = opts->xopts; xopt != opts->xopts + opts->xopts_nr; xopt++)
parse_merge_opt(&o, *xopt);
clean = merge_trees(&o,
@@ -306,7 +325,7 @@ static int do_recursive_merge(struct commit *base, struct commit *next,
(write_cache(index_fd, active_cache, active_nr) ||
commit_locked_index(&index_lock)))
/* TRANSLATORS: %s will be "revert" or "cherry-pick" */
- die(_("%s: Unable to write new index file"), me);
+ die(_("%s: Unable to write new index file"), action_name(opts));
rollback_lock_file(&index_lock);
if (!clean) {
@@ -335,7 +354,7 @@ static int do_recursive_merge(struct commit *base, struct commit *next,
* If we are revert, or if our cherry-pick results in a hand merge,
* we had better say that the current user is responsible for that.
*/
-static int run_git_commit(const char *defmsg)
+static int run_git_commit(const char *defmsg, struct replay_opts *opts)
{
/* 6 is max possible length of our args array including NULL */
const char *args[6];
@@ -343,9 +362,9 @@ static int run_git_commit(const char *defmsg)
args[i++] = "commit";
args[i++] = "-n";
- if (signoff)
+ if (opts->signoff)
args[i++] = "-s";
- if (!edit) {
+ if (!opts->edit) {
args[i++] = "-F";
args[i++] = defmsg;
}
@@ -354,7 +373,7 @@ static int run_git_commit(const char *defmsg)
return run_command_v_opt(args, RUN_GIT_CMD);
}
-static int do_pick_commit(struct commit *commit)
+static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
{
unsigned char head[20];
struct commit *base, *next, *parent;
@@ -364,7 +383,7 @@ static int do_pick_commit(struct commit *commit)
struct strbuf msgbuf = STRBUF_INIT;
int res;
- if (no_commit) {
+ if (opts->no_commit) {
/*
* We do not intend to commit immediately. We just want to
* merge the differences in, so let's compute the tree
@@ -377,7 +396,7 @@ static int do_pick_commit(struct commit *commit)
if (get_sha1("HEAD", head))
die (_("You do not have a valid HEAD"));
if (index_differs_from("HEAD", 0))
- die_dirty_index(me);
+ die_dirty_index(opts);
}
discard_cache();
@@ -389,32 +408,32 @@ static int do_pick_commit(struct commit *commit)
int cnt;
struct commit_list *p;
- if (!mainline)
+ if (!opts->mainline)
die(_("Commit %s is a merge but no -m option was given."),
sha1_to_hex(commit->object.sha1));
for (cnt = 1, p = commit->parents;
- cnt != mainline && p;
+ cnt != opts->mainline && p;
cnt++)
p = p->next;
- if (cnt != mainline || !p)
+ if (cnt != opts->mainline || !p)
die(_("Commit %s does not have parent %d"),
- sha1_to_hex(commit->object.sha1), mainline);
+ sha1_to_hex(commit->object.sha1), opts->mainline);
parent = p->item;
- } else if (0 < mainline)
+ } else if (0 < opts->mainline)
die(_("Mainline was specified but commit %s is not a merge."),
sha1_to_hex(commit->object.sha1));
else
parent = commit->parents->item;
- if (allow_ff && parent && !hashcmp(parent->object.sha1, head))
+ if (opts->allow_ff && parent && !hashcmp(parent->object.sha1, head))
return fast_forward_to(commit->object.sha1, head);
if (parent && parse_commit(parent) < 0)
/* TRANSLATORS: The first %s will be "revert" or
"cherry-pick", the second %s a SHA1 */
die(_("%s: cannot parse parent commit %s"),
- me, sha1_to_hex(parent->object.sha1));
+ action_name(opts), sha1_to_hex(parent->object.sha1));
if (get_message(commit, &msg) != 0)
die(_("Cannot get commit message for %s"),
@@ -429,7 +448,7 @@ static int do_pick_commit(struct commit *commit)
defmsg = git_pathdup("MERGE_MSG");
- if (action == REVERT) {
+ if (opts->action == REVERT) {
base = commit;
base_label = msg.label;
next = parent;
@@ -463,18 +482,18 @@ static int do_pick_commit(struct commit *commit)
strbuf_addstr(&msgbuf, p);
}
- if (record_origin) {
+ if (opts->record_origin) {
strbuf_addstr(&msgbuf, "(cherry picked from commit ");
strbuf_addstr(&msgbuf, sha1_to_hex(commit->object.sha1));
strbuf_addstr(&msgbuf, ")\n");
}
- if (!no_commit)
+ if (!opts->no_commit)
write_cherry_pick_head(commit);
}
- if (!strategy || !strcmp(strategy, "recursive") || action == REVERT) {
+ if (!opts->strategy || !strcmp(opts->strategy, "recursive") || opts->action == REVERT) {
res = do_recursive_merge(base, next, base_label, next_label,
- head, &msgbuf);
+ head, &msgbuf, opts);
write_message(&msgbuf, defmsg);
} else {
struct commit_list *common = NULL;
@@ -484,23 +503,23 @@ static int do_pick_commit(struct commit *commit)
commit_list_insert(base, &common);
commit_list_insert(next, &remotes);
- res = try_merge_command(strategy, xopts_nr, xopts, common,
- sha1_to_hex(head), remotes);
+ res = try_merge_command(opts->strategy, opts->xopts_nr, opts->xopts,
+ common, sha1_to_hex(head), remotes);
free_commit_list(common);
free_commit_list(remotes);
}
if (res) {
- error(action == REVERT
+ error(opts->action == REVERT
? _("could not revert %s... %s")
: _("could not apply %s... %s"),
find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV),
msg.subject);
print_advice();
- rerere(allow_rerere_auto);
+ rerere(opts->allow_rerere_auto);
} else {
- if (!no_commit)
- res = run_git_commit(defmsg);
+ if (!opts->no_commit)
+ res = run_git_commit(defmsg, opts);
}
free_message(&msg);
@@ -509,18 +528,18 @@ static int do_pick_commit(struct commit *commit)
return res;
}
-static void prepare_revs(struct rev_info *revs)
+static void prepare_revs(struct rev_info *revs, struct replay_opts *opts)
{
int argc;
init_revisions(revs, NULL);
revs->no_walk = 1;
- if (action != REVERT)
+ if (opts->action != REVERT)
revs->reverse = 1;
- argc = setup_revisions(commit_argc, commit_argv, revs, NULL);
+ argc = setup_revisions(opts->commit_argc, opts->commit_argv, revs, NULL);
if (argc > 1)
- usage(*revert_or_cherry_pick_usage());
+ usage(*revert_or_cherry_pick_usage(opts));
if (prepare_revision_walk(revs))
die(_("revision walk setup failed"));
@@ -529,48 +548,48 @@ static void prepare_revs(struct rev_info *revs)
die(_("empty commit set passed"));
}
-static void read_and_refresh_cache(const char *me)
+static void read_and_refresh_cache(struct replay_opts *opts)
{
static struct lock_file index_lock;
int index_fd = hold_locked_index(&index_lock, 0);
if (read_index_preload(&the_index, NULL) < 0)
- die(_("git %s: failed to read the index"), me);
+ die(_("git %s: failed to read the index"), action_name(opts));
refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, NULL, NULL, NULL);
if (the_index.cache_changed) {
if (write_index(&the_index, index_fd) ||
commit_locked_index(&index_lock))
- die(_("git %s: failed to refresh the index"), me);
+ die(_("git %s: failed to refresh the index"), action_name(opts));
}
rollback_lock_file(&index_lock);
}
-static int revert_or_cherry_pick(int argc, const char **argv)
+static int revert_or_cherry_pick(int argc, const char **argv,
+ struct replay_opts *opts)
{
struct rev_info revs;
struct commit *commit;
git_config(git_default_config, NULL);
- me = action == REVERT ? "revert" : "cherry-pick";
- setenv(GIT_REFLOG_ACTION, me, 0);
- parse_args(argc, argv);
+ setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
+ parse_args(argc, argv, opts);
- if (allow_ff) {
- if (signoff)
+ if (opts->allow_ff) {
+ if (opts->signoff)
die(_("cherry-pick --ff cannot be used with --signoff"));
- if (no_commit)
+ if (opts->no_commit)
die(_("cherry-pick --ff cannot be used with --no-commit"));
- if (record_origin)
+ if (opts->record_origin)
die(_("cherry-pick --ff cannot be used with -x"));
- if (edit)
+ if (opts->edit)
die(_("cherry-pick --ff cannot be used with --edit"));
}
- read_and_refresh_cache(me);
+ read_and_refresh_cache(opts);
- prepare_revs(&revs);
+ prepare_revs(&revs, opts);
while ((commit = get_revision(&revs))) {
- int res = do_pick_commit(commit);
+ int res = do_pick_commit(commit, opts);
if (res)
return res;
}
@@ -580,14 +599,20 @@ static int revert_or_cherry_pick(int argc, const char **argv)
int cmd_revert(int argc, const char **argv, const char *prefix)
{
+ struct replay_opts opts;
+
+ memset(&opts, 0, sizeof(opts));
if (isatty(0))
- edit = 1;
- action = REVERT;
- return revert_or_cherry_pick(argc, argv);
+ opts.edit = 1;
+ opts.action = REVERT;
+ return revert_or_cherry_pick(argc, argv, &opts);
}
int cmd_cherry_pick(int argc, const char **argv, const char *prefix)
{
- action = CHERRY_PICK;
- return revert_or_cherry_pick(argc, argv);
+ struct replay_opts opts;
+
+ memset(&opts, 0, sizeof(opts));
+ opts.action = CHERRY_PICK;
+ return revert_or_cherry_pick(argc, argv, &opts);
}
--
1.7.6.351.gb35ac.dirty
^ permalink raw reply related
* [PATCH 08/18] revert: Separate cmdline parsing from functional code
From: Ramkumar Ramachandra @ 2011-08-04 10:39 UTC (permalink / raw)
To: Junio C Hamano
Cc: Git List, Jonathan Nieder, Christian Couder, Daniel Barkalow,
Jeff King
In-Reply-To: <1312454356-3070-1-git-send-email-artagnon@gmail.com>
Currently, revert_or_cherry_pick sets up a default git config, parses
command-line arguments, before preparing to pick commits. This makes
for a bad API as the central worry of callers is to assert whether or
not a conflict occured while cherry picking. The current API is like:
if (revert_or_cherry_pick(argc, argv, opts) < 0)
print "Something failed, we're not sure what"
Simplify and rename revert_or_cherry_pick to pick_commits so that it
only has the responsibility of setting up the revision walker and
picking commits in a loop. Transfer the remaining work to its
callers. Now, the API is simplified as:
if (parse_args(argc, argv, opts) < 0)
print "Can't parse arguments"
if (pick_commits(opts) < 0)
print "Error encountered in picking machinery"
Later in the series, pick_commits will also serve as the starting
point for continuing a cherry-pick or revert.
Inspired-by: Christian Couder <chriscool@tuxfamily.org>
Helped-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
builtin/revert.c | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/builtin/revert.c b/builtin/revert.c
index 50f72de..90fe2ef 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -563,16 +563,12 @@ static void read_and_refresh_cache(struct replay_opts *opts)
rollback_lock_file(&index_lock);
}
-static int revert_or_cherry_pick(int argc, const char **argv,
- struct replay_opts *opts)
+static int pick_commits(struct replay_opts *opts)
{
struct rev_info revs;
struct commit *commit;
- git_config(git_default_config, NULL);
setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
- parse_args(argc, argv, opts);
-
if (opts->allow_ff) {
if (opts->signoff)
die(_("cherry-pick --ff cannot be used with --signoff"));
@@ -605,7 +601,9 @@ int cmd_revert(int argc, const char **argv, const char *prefix)
if (isatty(0))
opts.edit = 1;
opts.action = REVERT;
- return revert_or_cherry_pick(argc, argv, &opts);
+ git_config(git_default_config, NULL);
+ parse_args(argc, argv, &opts);
+ return pick_commits(&opts);
}
int cmd_cherry_pick(int argc, const char **argv, const char *prefix)
@@ -614,5 +612,7 @@ int cmd_cherry_pick(int argc, const char **argv, const char *prefix)
memset(&opts, 0, sizeof(opts));
opts.action = CHERRY_PICK;
- return revert_or_cherry_pick(argc, argv, &opts);
+ git_config(git_default_config, NULL);
+ parse_args(argc, argv, &opts);
+ return pick_commits(&opts);
}
--
1.7.6.351.gb35ac.dirty
^ permalink raw reply related
* [PATCH 09/18] revert: Don't create invalid replay_opts in parse_args
From: Ramkumar Ramachandra @ 2011-08-04 10:39 UTC (permalink / raw)
To: Junio C Hamano
Cc: Git List, Jonathan Nieder, Christian Couder, Daniel Barkalow,
Jeff King
In-Reply-To: <1312454356-3070-1-git-send-email-artagnon@gmail.com>
The "--ff" command-line option cannot be used with some other
command-line options. However, parse_args still parses these
incompatible options into a replay_opts structure for use by the rest
of the program. Although pick_commits, the current gatekeeper to the
cherry-pick machinery, checks the validity of the replay_opts
structure before before starting its operation, there will be multiple
entry points to the cherry-pick machinery in future. To futureproof
the code and catch these errors in one place, make sure that an
invalid replay_opts structure is not created by parse_args in the
first place. We still check the replay_opts structure for validity in
pick_commits, but this is an assert() now to emphasize that it's the
caller's responsibility to get it right.
Inspired-by: Christian Couder <chriscool@tuxfamily.org>
Mentored-by: Jonathan Nieder <jrnieder@gmail.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
builtin/revert.c | 38 +++++++++++++++++++++++++++-----------
1 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/builtin/revert.c b/builtin/revert.c
index 90fe2ef..f75c9cb 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -86,9 +86,26 @@ static int option_parse_x(const struct option *opt,
return 0;
}
+static void verify_opt_compatible(const char *me, const char *base_opt, ...)
+{
+ const char *this_opt;
+ va_list ap;
+
+ va_start(ap, base_opt);
+ while ((this_opt = va_arg(ap, const char *))) {
+ if (va_arg(ap, int))
+ break;
+ }
+ va_end(ap);
+
+ if (this_opt)
+ die(_("%s: %s cannot be used with %s"), me, this_opt, base_opt);
+}
+
static void parse_args(int argc, const char **argv, struct replay_opts *opts)
{
const char * const * usage_str = revert_or_cherry_pick_usage(opts);
+ const char *me = action_name(opts);
int noop;
struct option options[] = {
OPT_BOOLEAN('n', "no-commit", &opts->no_commit, "don't automatically commit"),
@@ -122,6 +139,13 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
if (opts->commit_argc < 2)
usage_with_options(usage_str, options);
+ if (opts->allow_ff)
+ verify_opt_compatible(me, "--ff",
+ "--signoff", opts->signoff,
+ "--no-commit", opts->no_commit,
+ "-x", opts->record_origin,
+ "--edit", opts->edit,
+ NULL);
opts->commit_argv = argv;
}
@@ -569,17 +593,9 @@ static int pick_commits(struct replay_opts *opts)
struct commit *commit;
setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
- if (opts->allow_ff) {
- if (opts->signoff)
- die(_("cherry-pick --ff cannot be used with --signoff"));
- if (opts->no_commit)
- die(_("cherry-pick --ff cannot be used with --no-commit"));
- if (opts->record_origin)
- die(_("cherry-pick --ff cannot be used with -x"));
- if (opts->edit)
- die(_("cherry-pick --ff cannot be used with --edit"));
- }
-
+ if (opts->allow_ff)
+ assert(!(opts->signoff || opts->no_commit ||
+ opts->record_origin || opts->edit));
read_and_refresh_cache(opts);
prepare_revs(&revs, opts);
--
1.7.6.351.gb35ac.dirty
^ permalink raw reply related
* [PATCH 10/18] revert: Save data for continuing after conflict resolution
From: Ramkumar Ramachandra @ 2011-08-04 10:39 UTC (permalink / raw)
To: Junio C Hamano
Cc: Git List, Jonathan Nieder, Christian Couder, Daniel Barkalow,
Jeff King
In-Reply-To: <1312454356-3070-1-git-send-email-artagnon@gmail.com>
Ever since v1.7.2-rc1~4^2~7 (revert: allow cherry-picking more than
one commit, 2010-06-02), a single invocation of "git cherry-pick" or
"git revert" can perform picks of several individual commits. To
implement features like "--continue" to continue the whole operation,
we will need to store some information about the state and the plan at
the beginning. Introduce a ".git/sequencer/head" file to store this
state, and ".git/sequencer/todo" file to store the plan. The head
file contains the SHA-1 of the HEAD before the start of the operation,
and the todo file contains an instruction sheet whose format is
inspired by the format of the "rebase -i" instruction sheet. As a
result, a typical todo file looks like:
pick 8537f0e submodule add: test failure when url is not configured
pick 4d68932 submodule add: allow relative repository path
pick f22a17e submodule add: clean up duplicated code
pick 59a5775 make copy_ref globally available
Since SHA-1 hex is abbreviated using an find_unique_abbrev(), it is
unambiguous. This does not guarantee that there will be no ambiguity
when more objects are added to the repository.
These two files alone are not enough to implement a "--continue" that
remembers the command-line options specified; later patches in the
series save them too.
These new files are unrelated to the existing .git/CHERRY_PICK_HEAD,
which will still be useful while committing after a conflict
resolution.
Inspired-by: Christian Couder <chriscool@tuxfamily.org>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
builtin/revert.c | 134 +++++++++++++++++++++++++++++++++++++-
t/t3510-cherry-pick-sequence.sh | 48 ++++++++++++++
2 files changed, 178 insertions(+), 4 deletions(-)
create mode 100755 t/t3510-cherry-pick-sequence.sh
diff --git a/builtin/revert.c b/builtin/revert.c
index f75c9cb..54df8a2 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -13,6 +13,7 @@
#include "rerere.h"
#include "merge-recursive.h"
#include "refs.h"
+#include "dir.h"
/*
* This implements the builtins revert and cherry-pick.
@@ -60,6 +61,10 @@ struct replay_opts {
#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
+#define SEQ_DIR "sequencer"
+#define SEQ_HEAD_FILE "sequencer/head"
+#define SEQ_TODO_FILE "sequencer/todo"
+
static const char *action_name(const struct replay_opts *opts)
{
return opts->action == REVERT ? "revert" : "cherry-pick";
@@ -587,10 +592,116 @@ static void read_and_refresh_cache(struct replay_opts *opts)
rollback_lock_file(&index_lock);
}
-static int pick_commits(struct replay_opts *opts)
+/*
+ * Append a commit to the end of the commit_list.
+ *
+ * next starts by pointing to the variable that holds the head of an
+ * empty commit_list, and is updated to point to the "next" field of
+ * the last item on the list as new commits are appended.
+ *
+ * Usage example:
+ *
+ * struct commit_list *list;
+ * struct commit_list **next = &list;
+ *
+ * next = commit_list_append(c1, next);
+ * next = commit_list_append(c2, next);
+ * assert(commit_list_count(list) == 2);
+ * return list;
+ */
+struct commit_list **commit_list_append(struct commit *commit,
+ struct commit_list **next)
+{
+ struct commit_list *new = xmalloc(sizeof(struct commit_list));
+ new->item = commit;
+ *next = new;
+ new->next = NULL;
+ return &new->next;
+}
+
+static int format_todo(struct strbuf *buf, struct commit_list *todo_list,
+ struct replay_opts *opts)
+{
+ struct commit_list *cur = NULL;
+ struct commit_message msg = { NULL, NULL, NULL, NULL, NULL };
+ const char *sha1_abbrev = NULL;
+ const char *action_str = opts->action == REVERT ? "revert" : "pick";
+
+ for (cur = todo_list; cur; cur = cur->next) {
+ sha1_abbrev = find_unique_abbrev(cur->item->object.sha1, DEFAULT_ABBREV);
+ if (get_message(cur->item, &msg))
+ return error(_("Cannot get commit message for %s"), sha1_abbrev);
+ strbuf_addf(buf, "%s %s %s\n", action_str, sha1_abbrev, msg.subject);
+ }
+ return 0;
+}
+
+static void walk_revs_populate_todo(struct commit_list **todo_list,
+ struct replay_opts *opts)
{
struct rev_info revs;
struct commit *commit;
+ struct commit_list **next;
+
+ prepare_revs(&revs, opts);
+
+ next = todo_list;
+ while ((commit = get_revision(&revs)))
+ next = commit_list_append(commit, next);
+}
+
+static void create_seq_dir(void)
+{
+ const char *seq_dir = git_path(SEQ_DIR);
+
+ if (!(file_exists(seq_dir) && is_directory(seq_dir))
+ && mkdir(seq_dir, 0777) < 0)
+ die_errno(_("Could not create sequencer directory '%s'."), seq_dir);
+}
+
+static void save_head(const char *head)
+{
+ const char *head_file = git_path(SEQ_HEAD_FILE);
+ static struct lock_file head_lock;
+ struct strbuf buf = STRBUF_INIT;
+ int fd;
+
+ fd = hold_lock_file_for_update(&head_lock, head_file, LOCK_DIE_ON_ERROR);
+ strbuf_addf(&buf, "%s\n", head);
+ if (write_in_full(fd, buf.buf, buf.len) < 0)
+ die_errno(_("Could not write to %s."), head_file);
+ if (commit_lock_file(&head_lock) < 0)
+ die(_("Error wrapping up %s."), head_file);
+}
+
+static void save_todo(struct commit_list *todo_list, struct replay_opts *opts)
+{
+ const char *todo_file = git_path(SEQ_TODO_FILE);
+ static struct lock_file todo_lock;
+ struct strbuf buf = STRBUF_INIT;
+ int fd;
+
+ fd = hold_lock_file_for_update(&todo_lock, todo_file, LOCK_DIE_ON_ERROR);
+ if (format_todo(&buf, todo_list, opts) < 0)
+ die(_("Could not format %s."), todo_file);
+ if (write_in_full(fd, buf.buf, buf.len) < 0) {
+ strbuf_release(&buf);
+ die_errno(_("Could not write to %s."), todo_file);
+ }
+ if (commit_lock_file(&todo_lock) < 0) {
+ strbuf_release(&buf);
+ die(_("Error wrapping up %s."), todo_file);
+ }
+ strbuf_release(&buf);
+}
+
+static int pick_commits(struct replay_opts *opts)
+{
+ struct commit_list *todo_list = NULL;
+ struct strbuf buf = STRBUF_INIT;
+ unsigned char sha1[20];
+ struct commit_list *cur;
+ int res;
setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
if (opts->allow_ff)
@@ -598,14 +709,29 @@ static int pick_commits(struct replay_opts *opts)
opts->record_origin || opts->edit));
read_and_refresh_cache(opts);
- prepare_revs(&revs, opts);
+ walk_revs_populate_todo(&todo_list, opts);
+ create_seq_dir();
+ if (get_sha1("HEAD", sha1)) {
+ if (opts->action == REVERT)
+ die(_("Can't revert as initial commit"));
+ die(_("Can't cherry-pick into empty head"));
+ }
+ save_head(sha1_to_hex(sha1));
- while ((commit = get_revision(&revs))) {
- int res = do_pick_commit(commit, opts);
+ for (cur = todo_list; cur; cur = cur->next) {
+ save_todo(cur, opts);
+ res = do_pick_commit(cur->item, opts);
if (res)
return res;
}
+ /*
+ * Sequence of picks finished successfully; cleanup by
+ * removing the .git/sequencer directory
+ */
+ strbuf_addf(&buf, "%s", git_path(SEQ_DIR));
+ remove_dir_recursively(&buf, 0);
+ strbuf_release(&buf);
return 0;
}
diff --git a/t/t3510-cherry-pick-sequence.sh b/t/t3510-cherry-pick-sequence.sh
new file mode 100755
index 0000000..a2c70ad
--- /dev/null
+++ b/t/t3510-cherry-pick-sequence.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+test_description='Test cherry-pick continuation features
+
+ + anotherpick: rewrites foo to d
+ + picked: rewrites foo to c
+ + unrelatedpick: rewrites unrelated to reallyunrelated
+ + base: rewrites foo to b
+ + initial: writes foo as a, unrelated as unrelated
+
+'
+
+. ./test-lib.sh
+
+pristine_detach () {
+ rm -rf .git/sequencer &&
+ git checkout -f "$1^0" &&
+ git read-tree -u --reset HEAD &&
+ git clean -d -f -f -q -x
+}
+
+test_expect_success setup '
+ echo unrelated >unrelated &&
+ git add unrelated &&
+ test_commit initial foo a &&
+ test_commit base foo b &&
+ test_commit unrelatedpick unrelated reallyunrelated &&
+ test_commit picked foo c &&
+ test_commit anotherpick foo d &&
+ git config advice.detachedhead false
+
+'
+
+test_expect_success 'cherry-pick persists data on failure' '
+ pristine_detach initial &&
+ test_must_fail git cherry-pick base..anotherpick &&
+ test_path_is_dir .git/sequencer &&
+ test_path_is_file .git/sequencer/head &&
+ test_path_is_file .git/sequencer/todo
+'
+
+test_expect_success 'cherry-pick cleans up sequencer state upon success' '
+ pristine_detach initial &&
+ git cherry-pick initial..picked &&
+ test_path_is_missing .git/sequencer
+'
+
+test_done
--
1.7.6.351.gb35ac.dirty
^ permalink raw reply related
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