* Re: [PATCH v3 21/21] Documentation/git-update-index: explain splitIndex.*
From: Christian Couder @ 2017-01-02 16:04 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Nguyen Thai Ngoc Duy, Ævar Arnfjörð Bjarmason,
Christian Couder
In-Reply-To: <xmqq8tr19ocs.fsf@gitster.mtv.corp.google.com>
On Tue, Dec 27, 2016 at 8:13 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Christian Couder <christian.couder@gmail.com> writes:
>
>> --split-index::
>> --no-split-index::
>> - Enable or disable split index mode. If enabled, the index is
>> - split into two files, $GIT_DIR/index and $GIT_DIR/sharedindex.<SHA-1>.
>> - Changes are accumulated in $GIT_DIR/index while the shared
>> - index file contains all index entries stays unchanged. If
>> - split-index mode is already enabled and `--split-index` is
>> - given again, all changes in $GIT_DIR/index are pushed back to
>> - the shared index file. This mode is designed for very large
>> - indexes that take a significant amount of time to read or write.
>> + Enable or disable split index mode. If split-index mode is
>> + already enabled and `--split-index` is given again, all
>> + changes in $GIT_DIR/index are pushed back to the shared index
>> + file.
>
> In the world after this series that introduced the percentage-based
> auto consolidation, it smells strange, or even illogical, that index
> is un-split after doing this:
>
> $ git update-index --split-index
> $ git update-index --split-index
>
> Before this series, it may have been a quick and dirty way to force
> consolidating the split index without totally disabling the feature,
> i.e. it would have looked more like
>
> $ git update-index --split-index
> ... work work work to accumulate more modifications
> ... consolidate into one --- there was no other way than
> ... disabling it temporarily
> $ git update-index --no-split-index
> ... but the user likes the feature so re-enable it.
> $ git update-index --split-index
>
> which I guess is where this strange behaviour comes from.
>
> It may be something we need to fix to unconfuse the end-users after
> this series lands. Even though "first disable and then re-enable"
> takes two commands (as opposed to one), it is far more logical. And
> the percentage-based auto consolidation feature is meant to reduce
> the need for manual consolidation, so it probably makes sense to
> remove this illogical feature.
Yeah, I tend to agree that this feature could be removed later. Though
before removing it, I'd like to hear Duy's opinion on this as he
created the feature in the first place.
>> @@ -394,6 +390,31 @@ Although this bit looks similar to assume-unchanged bit, its goal is
>> different from assume-unchanged bit's. Skip-worktree also takes
>> precedence over assume-unchanged bit when both are set.
>>
>> +Split index
>> +-----------
>> +
>> +This mode is designed for very large indexes that take a significant
>> +amount of time to read or write.
>
> This is not a new problem, but it probably is incorrect to say "to
> read or write". It saves time by not rewriting the whole thing but
> instead write out only the updated bits. You'd still read the whole
> thing while populating the in-core index from the disk, and if
> anything, you'd probably spend _more_ cycles because you'd essentially
> be reading the base and then reading the delta to apply on top.
Ok, then what about:
+This mode is designed for repositories with very large indexes, and aims
+at reducing the time it takes to repeatedly write these indexes.
>> +To avoid deleting a shared index file that is still used, its mtime is
>> +updated to the current time everytime a new split index based on the
>> +shared index file is either created or read from.
>
> The same comment on the mention of "mtime" in another patch applies
> here as well.
Ok, I will use "modification time" instead of "mtime".
Thanks.
^ permalink raw reply
* [PATCH 2/2] giteveryday: unbreak rendering with AsciiDoctor
From: Johannes Schindelin @ 2017-01-02 16:04 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano
In-Reply-To: <cover.1483373021.git.johannes.schindelin@gmx.de>
The "giteveryday" document has a callout list that contains a code
block. This is not a problem for AsciiDoc, but AsciiDoctor sadly was
explicitly designed *not* to render this correctly [*1*]. The symptom is
an unhelpful
line 322: callout list item index: expected 1 got 12
line 325: no callouts refer to list item 1
line 325: callout list item index: expected 2 got 13
line 327: no callouts refer to list item 2
In Git for Windows, we rely on the speed improvement of AsciiDoctor (on
this developer's machine, `make -j15 html` takes roughly 30 seconds with
AsciiDoctor, 70 seconds with AsciiDoc), therefore we need a way to
render this correctly.
The easiest way out is to simplify the callout list, as suggested by
AsciiDoctor's author, even while one may very well disagree with him
that a code block hath no place in a callout list.
*1*: https://github.com/asciidoctor/asciidoctor/issues/1478
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
Documentation/giteveryday.txt | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/Documentation/giteveryday.txt b/Documentation/giteveryday.txt
index 35473ad02f..10c8ff93c0 100644
--- a/Documentation/giteveryday.txt
+++ b/Documentation/giteveryday.txt
@@ -307,9 +307,16 @@ master or exposed as a part of a stable branch.
<9> backport a critical fix.
<10> create a signed tag.
<11> make sure master was not accidentally rewound beyond that
-already pushed out. `ko` shorthand points at the Git maintainer's
+already pushed out.
+<12> In the output from `git show-branch`, `master` should have
+everything `ko/master` has, and `next` should have
+everything `ko/next` has, etc.
+<13> push out the bleeding edge, together with new tags that point
+into the pushed history.
+
+In this example, the `ko` shorthand points at the Git maintainer's
repository at kernel.org, and looks like this:
-+
+
------------
(in .git/config)
[remote "ko"]
@@ -320,12 +327,6 @@ repository at kernel.org, and looks like this:
push = +refs/heads/pu
push = refs/heads/maint
------------
-+
-<12> In the output from `git show-branch`, `master` should have
-everything `ko/master` has, and `next` should have
-everything `ko/next` has, etc.
-<13> push out the bleeding edge, together with new tags that point
-into the pushed history.
Repository Administration[[ADMINISTRATION]]
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH 1/2] asciidoctor: fix user-manual to be built by `asciidoctor`
From: Johannes Schindelin @ 2017-01-02 16:03 UTC (permalink / raw)
To: git; +Cc: 마누엘, Junio C Hamano
In-Reply-To: <cover.1483373021.git.johannes.schindelin@gmx.de>
[-- Attachment #1: Type: text/plain, Size: 1789 bytes --]
From: =?UTF-8?q?=EB=A7=88=EB=88=84=EC=97=98?= <nalla@hamal.uberspace.de>
The `user-manual.txt` is designed as a `book` but the `Makefile` wants
to build it as an `article`. This seems to be a problem when building
the documentation with `asciidoctor`. Furthermore the parts *Git
Glossary* and *Appendix B* had no subsections which is not allowed when
building with `asciidoctor`. So lets add a *dummy* section.
Signed-off-by: 마누엘 <nalla@hamal.uberspace.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
Documentation/Makefile | 2 +-
Documentation/user-manual.txt | 8 ++++++++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/Documentation/Makefile b/Documentation/Makefile
index b43d66eae6..a9fb497b83 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -337,7 +337,7 @@ manpage-base-url.xsl: manpage-base-url.xsl.in
user-manual.xml: user-manual.txt user-manual.conf
$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
- $(TXT_TO_XML) -d article -o $@+ $< && \
+ $(TXT_TO_XML) -d book -o $@+ $< && \
mv $@+ $@
technical/api-index.txt: technical/api-index-skel.txt \
diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt
index 5e07454572..bc29298678 100644
--- a/Documentation/user-manual.txt
+++ b/Documentation/user-manual.txt
@@ -4395,6 +4395,10 @@ itself!
Git Glossary
============
+[[git-explained]]
+Git explained
+-------------
+
include::glossary-content.txt[]
[[git-quick-start]]
@@ -4636,6 +4640,10 @@ $ git gc
Appendix B: Notes and todo list for this manual
===============================================
+[[todo-list]]
+Todo list
+---------
+
This is a work in progress.
The basic requirements:
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH 0/2] Fix the documentation to build with asciidoctor
From: Johannes Schindelin @ 2017-01-02 16:03 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano
[-- Attachment #1: Type: text/plain, Size: 2856 bytes --]
The first patch in this series has been with Git for Windows for well
over a year already, the second one is a replacement for such an old
patch.
The reason why we use asciidoctor in Git for Windows is easy to see:
when building new Git for Windows packages, rendering the documentation
dominates the time by far. It takes roughly 75 seconds to compile all
the executables from scratch on my main work machine, but it takes
roughly 125 seconds to build the documentation from scratch.
Out of those 125 seconds, 45 are taken by the HTML documentation.
In the Git for Windows project, we realized a long time ago that we
could reduce the time dramatically by using asciidoctor: it takes only
15 seconds to build the HTML documentation.
Those savings come at a cost, though: asciidoctor was designed to be
much less flexible than asciidoc, in favor for maximum speed and minimal
size of the code base. And to accomodate those shortcomings, it is
unfortunately necessary to change Git's documentation sources.
So what is the big deal with those timings? It's only half a minute!
This is on a very beefy machine. Internally, I use quite a bit of
Continuous Integration to build intermediate Git for Windows versions
for testing, and those builds are backed by reasonably-sized VMs. That
makes it worth shaving that extra time off.
Side note for the curious who wonder why asciidoctor is *so much* faster
than asciidoc: my gut feeling is that the primary reason for this is,
once again, the POSIX emulation layer: asciidoc runs as a Python script,
using a Python interpreter that uses the MSYS2 runtime for path
translation and fork emulation (among other things), while asciidoctor
runs as a Ruby script, using a pure Windows Ruby interpreter (for those
remembering the nomenclature: the Python interpreter is an MSYS2 program
while the Ruby interpreter is a MINGW program). But even after that I
suspect that asciidoc was just not designed for speed, on a very
fundamental level.
Now back to the patch series: I *hope* the patches are not too
disruptive. I am very open to changing them however needed, I only care
about one result in the end: that the documentation builds correctly
(and fast) with asciidoctor.
Johannes Schindelin (1):
giteveryday: unbreak rendering with AsciiDoctor
마누엘 (1):
asciidoctor: fix user-manual to be built by `asciidoctor`
Documentation/Makefile | 2 +-
Documentation/giteveryday.txt | 17 +++++++++--------
Documentation/user-manual.txt | 8 ++++++++
3 files changed, 18 insertions(+), 9 deletions(-)
base-commit: e05806da9ec4aff8adfed142ab2a2b3b02e33c8c
Published-As: https://github.com/dscho/git/releases/tag/asciidoctor-fixes-v1
Fetch-It-Via: git fetch https://github.com/dscho/git asciidoctor-fixes-v1
--
2.11.0.rc3.windows.1
^ permalink raw reply
* Re: [PATCH 00/17] object_id part 6
From: Michael Haggerty @ 2017-01-02 15:37 UTC (permalink / raw)
To: brian m. carlson, git; +Cc: Jeff King
In-Reply-To: <20170101191847.564741-1-sandals@crustytoothpaste.net>
On 01/01/2017 08:18 PM, brian m. carlson wrote:
> This is another series in the continuing conversion to struct object_id.
>
> This series converts more of the builtin directory and some of the
> refs code to use struct object_id. Additionally, it implements an
> nth_packed_object_oid function which provides a struct object_id
> version of the nth_packed_object function.
>
> There is a small known conflict with next, but it can easily be fixed up.
I read through all of the patches, and sent a few comments. I didn't
notice any other problems.
Michael
^ permalink raw reply
* [PATCH v3 38/38] sequencer (rebase -i): write out the final message
From: Johannes Schindelin @ 2017-01-02 15:36 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
The shell script version of the interactive rebase has a very specific
final message. Teach the sequencer to print the same.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/sequencer.c b/sequencer.c
index b39cd21e03..0e7d2ca5c8 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -2127,6 +2127,9 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
}
apply_autostash(opts);
+ fprintf(stderr, "Successfully rebased and updated %s.\n",
+ head_ref.buf);
+
strbuf_release(&buf);
strbuf_release(&head_ref);
}
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH v3 37/38] sequencer (rebase -i): write the progress into files
From: Johannes Schindelin @ 2017-01-02 15:36 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
For the benefit of e.g. the shell prompt, the interactive rebase not
only displays the progress for the user to see, but also writes it into
the msgnum/end files in the state directory.
Teach the sequencer this new trick.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 30 +++++++++++++++++++++++++++---
1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index 2c9c555ab6..b39cd21e03 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -47,6 +47,16 @@ static GIT_PATH_FUNC(rebase_path_todo, "rebase-merge/git-rebase-todo")
*/
static GIT_PATH_FUNC(rebase_path_done, "rebase-merge/done")
/*
+ * The file to keep track of how many commands were already processed (e.g.
+ * for the prompt).
+ */
+static GIT_PATH_FUNC(rebase_path_msgnum, "rebase-merge/msgnum");
+/*
+ * The file to keep track of how many commands are to be processed in total
+ * (e.g. for the prompt).
+ */
+static GIT_PATH_FUNC(rebase_path_msgtotal, "rebase-merge/end");
+/*
* The commit message that is planned to be used for any changes that
* need to be committed following a user interaction.
*/
@@ -1353,6 +1363,7 @@ static int read_populate_todo(struct todo_list *todo_list,
if (is_rebase_i(opts)) {
struct todo_list done = TODO_LIST_INIT;
+ FILE *f = fopen(rebase_path_msgtotal(), "w");
if (strbuf_read_file(&done.buf, rebase_path_done(), 0) > 0 &&
!parse_insn_buffer(done.buf.buf, &done))
@@ -1362,8 +1373,12 @@ static int read_populate_todo(struct todo_list *todo_list,
todo_list->total_nr = todo_list->done_nr
+ count_commands(todo_list);
-
todo_list_release(&done);
+
+ if (f) {
+ fprintf(f, "%d\n", todo_list->total_nr);
+ fclose(f);
+ }
}
return 0;
@@ -1947,11 +1962,20 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
if (save_todo(todo_list, opts))
return -1;
if (is_rebase_i(opts)) {
- if (item->command != TODO_COMMENT)
+ if (item->command != TODO_COMMENT) {
+ FILE *f = fopen(rebase_path_msgnum(), "w");
+
+ todo_list->done_nr++;
+
+ if (f) {
+ fprintf(f, "%d\n", todo_list->done_nr);
+ fclose(f);
+ }
fprintf(stderr, "Rebasing (%d/%d)%s",
- ++(todo_list->done_nr),
+ todo_list->done_nr,
todo_list->total_nr,
opts->verbose ? "\n" : "\r");
+ }
unlink(rebase_path_message());
unlink(rebase_path_author_script());
unlink(rebase_path_stopped_sha());
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH v3 36/38] sequencer (rebase -i): show the progress
From: Johannes Schindelin @ 2017-01-02 15:35 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
The interactive rebase keeps the user informed about its progress.
If the sequencer wants to do the grunt work of the interactive
rebase, it also needs to show that progress.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/sequencer.c b/sequencer.c
index 4792a3de3b..2c9c555ab6 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -1181,6 +1181,7 @@ struct todo_list {
struct strbuf buf;
struct todo_item *items;
int nr, alloc, current;
+ int done_nr, total_nr;
};
#define TODO_LIST_INIT { STRBUF_INIT }
@@ -1297,6 +1298,17 @@ static int parse_insn_buffer(char *buf, struct todo_list *todo_list)
return res;
}
+static int count_commands(struct todo_list *todo_list)
+{
+ int count = 0, i;
+
+ for (i = 0; i < todo_list->nr; i++)
+ if (todo_list->items[i].command != TODO_COMMENT)
+ count++;
+
+ return count;
+}
+
static int read_populate_todo(struct todo_list *todo_list,
struct replay_opts *opts)
{
@@ -1339,6 +1351,21 @@ static int read_populate_todo(struct todo_list *todo_list,
return error(_("cannot revert during a cherry-pick."));
}
+ if (is_rebase_i(opts)) {
+ struct todo_list done = TODO_LIST_INIT;
+
+ if (strbuf_read_file(&done.buf, rebase_path_done(), 0) > 0 &&
+ !parse_insn_buffer(done.buf.buf, &done))
+ todo_list->done_nr = count_commands(&done);
+ else
+ todo_list->done_nr = 0;
+
+ todo_list->total_nr = todo_list->done_nr
+ + count_commands(todo_list);
+
+ todo_list_release(&done);
+ }
+
return 0;
}
@@ -1920,6 +1947,11 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
if (save_todo(todo_list, opts))
return -1;
if (is_rebase_i(opts)) {
+ if (item->command != TODO_COMMENT)
+ fprintf(stderr, "Rebasing (%d/%d)%s",
+ ++(todo_list->done_nr),
+ todo_list->total_nr,
+ opts->verbose ? "\n" : "\r");
unlink(rebase_path_message());
unlink(rebase_path_author_script());
unlink(rebase_path_stopped_sha());
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH v3 35/38] sequencer (rebase -i): suggest --edit-todo upon unknown command
From: Johannes Schindelin @ 2017-01-02 15:35 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
This is the same behavior as known from `git rebase -i`.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/sequencer.c b/sequencer.c
index 4f37ba8d33..4792a3de3b 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -1314,8 +1314,12 @@ static int read_populate_todo(struct todo_list *todo_list,
close(fd);
res = parse_insn_buffer(todo_list->buf.buf, todo_list);
- if (res)
+ if (res) {
+ if (is_rebase_i(opts))
+ return error(_("please fix this using "
+ "'git rebase --edit-todo'."));
return error(_("unusable instruction sheet: '%s'"), todo_file);
+ }
if (!todo_list->nr &&
(!is_rebase_i(opts) || !file_exists(rebase_path_done())))
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH v3 34/38] sequencer (rebase -i): show only failed cherry-picks' output
From: Johannes Schindelin @ 2017-01-02 15:35 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
This is the behavior of the shell script version of the interactive
rebase, by using the `output` function defined in `git-rebase.sh`.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/sequencer.c b/sequencer.c
index a501dfce38..4f37ba8d33 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -433,6 +433,8 @@ static int do_recursive_merge(struct commit *base, struct commit *next,
o.ancestor = base ? base_label : "(empty tree)";
o.branch1 = "HEAD";
o.branch2 = next ? next_label : "(empty tree)";
+ if (is_rebase_i(opts))
+ o.buffer_output = 2;
head_tree = parse_tree_indirect(head);
next_tree = next ? next->tree : empty_tree();
@@ -444,6 +446,8 @@ static int do_recursive_merge(struct commit *base, struct commit *next,
clean = merge_trees(&o,
head_tree,
next_tree, base_tree, &result);
+ if (is_rebase_i(opts) && clean <= 0)
+ fputs(o.obuf.buf, stdout);
strbuf_release(&o.obuf);
if (clean < 0)
return clean;
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH v3 31/38] sequencer: make reading author-script more elegant
From: Johannes Schindelin @ 2017-01-02 15:35 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
Rather than abusing a strbuf to come up with an environment block, let's
just use the argv_array structure which serves the same purpose much
better.
While at it, rename the function to reflect the fact that it does not
really care exactly what environment variables are defined in said file.
Suggested-by: Jeff King <peff@peff.net>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 32 +++++++++++---------------------
1 file changed, 11 insertions(+), 21 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index 41f80ea2c4..a0d0aaeaf8 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -544,18 +544,17 @@ static int write_author_script(const char *message)
}
/*
- * Read the author-script file into an environment block, ready for use in
- * run_command(), that can be free()d afterwards.
+ * Read a list of environment variable assignments (such as the author-script
+ * file) into an environment block. Returns -1 on error, 0 otherwise.
*/
-static char **read_author_script(void)
+static int read_env_script(struct argv_array *env)
{
struct strbuf script = STRBUF_INIT;
int i, count = 0;
- char *p, *p2, **env;
- size_t env_size;
+ char *p, *p2;
if (strbuf_read_file(&script, rebase_path_author_script(), 256) <= 0)
- return NULL;
+ return -1;
for (p = script.buf; *p; p++)
if (skip_prefix(p, "'\\\\''", (const char **)&p2))
@@ -567,19 +566,12 @@ static char **read_author_script(void)
count++;
}
- env_size = (count + 1) * sizeof(*env);
- strbuf_grow(&script, env_size);
- memmove(script.buf + env_size, script.buf, script.len);
- p = script.buf + env_size;
- env = (char **)strbuf_detach(&script, NULL);
-
for (i = 0; i < count; i++) {
- env[i] = p;
+ argv_array_push(env, p);
p += strlen(p) + 1;
}
- env[count] = NULL;
- return env;
+ return 0;
}
static const char staged_changes_advice[] =
@@ -612,14 +604,12 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
int allow_empty, int edit, int amend,
int cleanup_commit_message)
{
- char **env = NULL;
- struct argv_array array;
+ struct argv_array env = ARGV_ARRAY_INIT, array;
int rc;
const char *value;
if (is_rebase_i(opts)) {
- env = read_author_script();
- if (!env) {
+ if (!read_env_script(&env)) {
const char *gpg_opt = gpg_sign_opt_quoted(opts);
return error(_(staged_changes_advice),
@@ -655,9 +645,9 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
argv_array_push(&array, "--allow-empty-message");
rc = run_command_v_opt_cd_env(array.argv, RUN_GIT_CMD, NULL,
- (const char *const *)env);
+ (const char *const *)env.argv);
argv_array_clear(&array);
- free(env);
+ argv_array_clear(&env);
return rc;
}
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH v3 33/38] sequencer (rebase -i): show only failed `git commit`'s output
From: Johannes Schindelin @ 2017-01-02 15:35 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
This is the behavior of the shell script version of the interactive
rebase, by using the `output` function defined in `git-rebase.sh`.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/sequencer.c b/sequencer.c
index c7dc5a2ad4..a501dfce38 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -610,6 +610,11 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
cmd.git_cmd = 1;
if (is_rebase_i(opts)) {
+ if (!edit) {
+ cmd.stdout_to_stderr = 1;
+ cmd.err = -1;
+ }
+
if (read_env_script(&cmd.env_array)) {
const char *gpg_opt = gpg_sign_opt_quoted(opts);
@@ -644,6 +649,19 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
if (opts->allow_empty_message)
argv_array_push(&cmd.args, "--allow-empty-message");
+ if (cmd.err == -1) {
+ /* hide stderr on success */
+ struct strbuf buf = STRBUF_INIT;
+ int rc = pipe_command(&cmd,
+ NULL, 0,
+ /* stdout is already redirected */
+ NULL, 0,
+ &buf, 0);
+ if (rc)
+ fputs(buf.buf, stderr);
+ strbuf_release(&buf);
+ return rc;
+ }
return run_command(&cmd);
}
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH v3 32/38] sequencer: use run_command() directly
From: Johannes Schindelin @ 2017-01-02 15:35 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
Instead of using the convenience function run_command_v_opt_cd_env(), we
now use the run_command() function. The former function is simply a
wrapper of the latter, trying to make it more convenient to use.
However, we already have to construct the argv and the env parameters,
and we will need even finer control e.g. over the output of the command,
so let's just stop using the convenience function.
Based on patches and suggestions by Johannes Sixt and Jeff King.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 36 ++++++++++++++++--------------------
1 file changed, 16 insertions(+), 20 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index a0d0aaeaf8..c7dc5a2ad4 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -604,12 +604,13 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
int allow_empty, int edit, int amend,
int cleanup_commit_message)
{
- struct argv_array env = ARGV_ARRAY_INIT, array;
- int rc;
+ struct child_process cmd = CHILD_PROCESS_INIT;
const char *value;
+ cmd.git_cmd = 1;
+
if (is_rebase_i(opts)) {
- if (!read_env_script(&env)) {
+ if (read_env_script(&cmd.env_array)) {
const char *gpg_opt = gpg_sign_opt_quoted(opts);
return error(_(staged_changes_advice),
@@ -617,39 +618,34 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
}
}
- argv_array_init(&array);
- argv_array_push(&array, "commit");
- argv_array_push(&array, "-n");
+ argv_array_push(&cmd.args, "commit");
+ argv_array_push(&cmd.args, "-n");
if (amend)
- argv_array_push(&array, "--amend");
+ argv_array_push(&cmd.args, "--amend");
if (opts->gpg_sign)
- argv_array_pushf(&array, "-S%s", opts->gpg_sign);
+ argv_array_pushf(&cmd.args, "-S%s", opts->gpg_sign);
if (opts->signoff)
- argv_array_push(&array, "-s");
+ argv_array_push(&cmd.args, "-s");
if (defmsg)
- argv_array_pushl(&array, "-F", defmsg, NULL);
+ argv_array_pushl(&cmd.args, "-F", defmsg, NULL);
if (cleanup_commit_message)
- argv_array_push(&array, "--cleanup=strip");
+ argv_array_push(&cmd.args, "--cleanup=strip");
if (edit)
- argv_array_push(&array, "-e");
+ argv_array_push(&cmd.args, "-e");
else if (!cleanup_commit_message &&
!opts->signoff && !opts->record_origin &&
git_config_get_value("commit.cleanup", &value))
- argv_array_push(&array, "--cleanup=verbatim");
+ argv_array_push(&cmd.args, "--cleanup=verbatim");
if (allow_empty)
- argv_array_push(&array, "--allow-empty");
+ argv_array_push(&cmd.args, "--allow-empty");
if (opts->allow_empty_message)
- argv_array_push(&array, "--allow-empty-message");
+ argv_array_push(&cmd.args, "--allow-empty-message");
- rc = run_command_v_opt_cd_env(array.argv, RUN_GIT_CMD, NULL,
- (const char *const *)env.argv);
- argv_array_clear(&array);
- argv_array_clear(&env);
- return rc;
+ return run_command(&cmd);
}
static int is_original_commit_empty(struct commit *commit)
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH v3 30/38] sequencer (rebase -i): differentiate between comments and 'noop'
From: Johannes Schindelin @ 2017-01-02 15:34 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
In the upcoming patch, we will support rebase -i's progress
reporting. The progress skips comments but counts 'noop's.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index 6e92f186ae..41f80ea2c4 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -737,7 +737,9 @@ enum todo_command {
TODO_EXEC,
/* commands that do nothing but are counted for reporting progress */
TODO_NOOP,
- TODO_DROP
+ TODO_DROP,
+ /* comments (not counted for reporting progress) */
+ TODO_COMMENT
};
static struct {
@@ -752,12 +754,13 @@ static struct {
{ 's', "squash" },
{ 'x', "exec" },
{ 0, "noop" },
- { 'd', "drop" }
+ { 'd', "drop" },
+ { 0, NULL }
};
static const char *command_to_string(const enum todo_command command)
{
- if ((size_t)command < ARRAY_SIZE(todo_command_info))
+ if (command < TODO_COMMENT)
return todo_command_info[command].str;
die("Unknown command: %d", command);
}
@@ -1198,14 +1201,14 @@ static int parse_insn_line(struct todo_item *item, const char *bol, char *eol)
bol += strspn(bol, " \t");
if (bol == eol || *bol == '\r' || *bol == comment_line_char) {
- item->command = TODO_NOOP;
+ item->command = TODO_COMMENT;
item->commit = NULL;
item->arg = bol;
item->arg_len = eol - bol;
return 0;
}
- for (i = 0; i < ARRAY_SIZE(todo_command_info); i++)
+ for (i = 0; i < TODO_COMMENT; i++)
if (skip_prefix(bol, todo_command_info[i].str, &bol)) {
item->command = i;
break;
@@ -1214,7 +1217,7 @@ static int parse_insn_line(struct todo_item *item, const char *bol, char *eol)
item->command = i;
break;
}
- if (i >= ARRAY_SIZE(todo_command_info))
+ if (i >= TODO_COMMENT)
return -1;
if (item->command == TODO_NOOP) {
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH v3 29/38] sequencer (rebase -i): implement the 'drop' command
From: Johannes Schindelin @ 2017-01-02 15:34 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
The parsing part of a 'drop' command is almost identical to parsing a
'pick', while the operation is the same as that of a 'noop'.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index dd5b843a84..6e92f186ae 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -736,7 +736,8 @@ enum todo_command {
/* commands that do something else than handling a single commit */
TODO_EXEC,
/* commands that do nothing but are counted for reporting progress */
- TODO_NOOP
+ TODO_NOOP,
+ TODO_DROP
};
static struct {
@@ -750,7 +751,8 @@ static struct {
{ 'f', "fixup" },
{ 's', "squash" },
{ 'x', "exec" },
- { 0, "noop" }
+ { 0, "noop" },
+ { 'd', "drop" }
};
static const char *command_to_string(const enum todo_command command)
@@ -762,7 +764,7 @@ static const char *command_to_string(const enum todo_command command)
static int is_noop(const enum todo_command command)
{
- return TODO_NOOP <= (size_t)command;
+ return TODO_NOOP <= command;
}
static int is_fixup(enum todo_command command)
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* Re: [PATCH 14/17] sha1_file: introduce an nth_packed_object_oid function
From: Michael Haggerty @ 2017-01-02 15:30 UTC (permalink / raw)
To: brian m. carlson, git; +Cc: Jeff King
In-Reply-To: <20170101191847.564741-15-sandals@crustytoothpaste.net>
On 01/01/2017 08:18 PM, brian m. carlson wrote:
> There are places in the code where we would like to provide a struct
> object_id *, yet read the hash directly from the pack. Provide an
> nth_packed_object_oid function that mirrors the nth_packed_object_sha1
> function.
>
> The required cast is questionable, but should be safe on all known
> platforms. The alternative of allocating an object as an intermediate
> would be too inefficient and cause memory leaks. If necessary, an
> intermediate union could be used; this practice is allowed by GCC and
> explicitly sanctioned by C11. However, such a change will likely not be
> necessary, and can be made if and when it is.
I have the feeling that this design decision has been discussed on the
mailing list. If so, could you include a URL here?
The obvious alternative to allocating a new object to return to the
caller would be to have the caller of `nth_packed_object_oid()` pass a
`struct object_id *` argument to be filled in (by copying the hash into
it). Aside from being legal C, this would also be a more robust step
towards a post-SHA-1 world, where the suggested hack wouldn't work.
Of course, the question is what the callers want to do with the
`object_id`. Are the return values of `nth_packed_object_sha1()` stored
to other longer-lived structures that rely on the lifetime of the
packfile mmap to keep the value valid? If so, then keeping track of the
lifetime of the `struct object_id` could be a big chore, not to mention
that needing to keep a 20-byte `struct object_id` around rather than a
8- or 4-byte pointer would also cost more RAM.
As you probably can tell, I'm not psyched about straying outside of
legal C. It would be nice to see more justification.
> [...]
Michael
^ permalink raw reply
* [PATCH v3 28/38] sequencer (rebase -i): allow rescheduling commands
From: Johannes Schindelin @ 2017-01-02 15:28 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
The interactive rebase has the very special magic that a cherry-pick
that exits with a status different from 0 and 1 signifies a failure to
even record that a cherry-pick was started.
This can happen e.g. when a fast-forward fails because it would
overwrite untracked files.
In that case, we must reschedule the command that we thought we already
had at least started successfully.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/sequencer.c b/sequencer.c
index 04a64cf0dc..dd5b843a84 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -1915,6 +1915,12 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
1);
res = do_pick_commit(item->command, item->commit,
opts, is_final_fixup(todo_list));
+ if (is_rebase_i(opts) && res < 0) {
+ /* Reschedule */
+ todo_list->current--;
+ if (save_todo(todo_list, opts))
+ return -1;
+ }
if (item->command == TODO_EDIT) {
struct commit *commit = item->commit;
if (!res)
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH v3 27/38] sequencer (rebase -i): respect strategy/strategy_opts settings
From: Johannes Schindelin @ 2017-01-02 15:28 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
The sequencer already has an idea about using different merge
strategies. We just piggy-back on top of that, using rebase -i's
own settings, when running the sequencer in interactive rebase mode.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/sequencer.c b/sequencer.c
index 06f7cebe48..04a64cf0dc 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -114,6 +114,8 @@ static GIT_PATH_FUNC(rebase_path_verbose, "rebase-merge/verbose")
static GIT_PATH_FUNC(rebase_path_head_name, "rebase-merge/head-name")
static GIT_PATH_FUNC(rebase_path_onto, "rebase-merge/onto")
static GIT_PATH_FUNC(rebase_path_autostash, "rebase-merge/autostash")
+static GIT_PATH_FUNC(rebase_path_strategy, "rebase-merge/strategy")
+static GIT_PATH_FUNC(rebase_path_strategy_opts, "rebase-merge/strategy_opts")
static inline int is_rebase_i(const struct replay_opts *opts)
{
@@ -1368,6 +1370,26 @@ static int populate_opts_cb(const char *key, const char *value, void *data)
return 0;
}
+static void read_strategy_opts(struct replay_opts *opts, struct strbuf *buf)
+{
+ int i;
+
+ strbuf_reset(buf);
+ if (!read_oneliner(buf, rebase_path_strategy(), 0))
+ return;
+ opts->strategy = strbuf_detach(buf, NULL);
+ if (!read_oneliner(buf, rebase_path_strategy_opts(), 0))
+ return;
+
+ opts->xopts_nr = split_cmdline(buf->buf, (const char ***)&opts->xopts);
+ for (i = 0; i < opts->xopts_nr; i++) {
+ const char *arg = opts->xopts[i];
+
+ skip_prefix(arg, "--", &arg);
+ opts->xopts[i] = xstrdup(arg);
+ }
+}
+
static int read_populate_opts(struct replay_opts *opts)
{
if (is_rebase_i(opts)) {
@@ -1381,11 +1403,13 @@ static int read_populate_opts(struct replay_opts *opts)
opts->gpg_sign = xstrdup(buf.buf + 2);
}
}
- strbuf_release(&buf);
if (file_exists(rebase_path_verbose()))
opts->verbose = 1;
+ read_strategy_opts(opts, &buf);
+ strbuf_release(&buf);
+
return 0;
}
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH v3 26/38] sequencer (rebase -i): respect the rebase.autostash setting
From: Johannes Schindelin @ 2017-01-02 15:28 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
Git's `rebase` command inspects the `rebase.autostash` config setting
to determine whether it should stash any uncommitted changes before
rebasing and re-apply them afterwards.
As we introduce more bits and pieces to let the sequencer act as
interactive rebase's backend, here is the part that adds support for
the autostash feature.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/sequencer.c b/sequencer.c
index 43ced8db31..06f7cebe48 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -113,6 +113,7 @@ static GIT_PATH_FUNC(rebase_path_orig_head, "rebase-merge/orig-head")
static GIT_PATH_FUNC(rebase_path_verbose, "rebase-merge/verbose")
static GIT_PATH_FUNC(rebase_path_head_name, "rebase-merge/head-name")
static GIT_PATH_FUNC(rebase_path_onto, "rebase-merge/onto")
+static GIT_PATH_FUNC(rebase_path_autostash, "rebase-merge/autostash")
static inline int is_rebase_i(const struct replay_opts *opts)
{
@@ -1801,6 +1802,47 @@ static enum todo_command peek_command(struct todo_list *todo_list, int offset)
return -1;
}
+static int apply_autostash(struct replay_opts *opts)
+{
+ struct strbuf stash_sha1 = STRBUF_INIT;
+ struct child_process child = CHILD_PROCESS_INIT;
+ int ret = 0;
+
+ if (!read_oneliner(&stash_sha1, rebase_path_autostash(), 1)) {
+ strbuf_release(&stash_sha1);
+ return 0;
+ }
+ strbuf_trim(&stash_sha1);
+
+ child.git_cmd = 1;
+ argv_array_push(&child.args, "stash");
+ argv_array_push(&child.args, "apply");
+ argv_array_push(&child.args, stash_sha1.buf);
+ if (!run_command(&child))
+ printf(_("Applied autostash."));
+ else {
+ struct child_process store = CHILD_PROCESS_INIT;
+
+ store.git_cmd = 1;
+ argv_array_push(&store.args, "stash");
+ argv_array_push(&store.args, "store");
+ argv_array_push(&store.args, "-m");
+ argv_array_push(&store.args, "autostash");
+ argv_array_push(&store.args, "-q");
+ argv_array_push(&store.args, stash_sha1.buf);
+ if (run_command(&store))
+ ret = error(_("cannot store %s"), stash_sha1.buf);
+ else
+ printf(_("Applying autostash resulted in conflicts.\n"
+ "Your changes are safe in the stash.\n"
+ "You can run \"git stash pop\" or"
+ " \"git stash drop\" at any time.\n"));
+ }
+
+ strbuf_release(&stash_sha1);
+ return ret;
+}
+
static const char *reflog_message(struct replay_opts *opts,
const char *sub_action, const char *fmt, ...)
{
@@ -1980,6 +2022,7 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
run_command(&hook);
}
}
+ apply_autostash(opts);
strbuf_release(&buf);
strbuf_release(&head_ref);
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH v3 22/38] sequencer (rebase -i): set the reflog message consistently
From: Johannes Schindelin @ 2017-01-02 15:28 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
We already used the same reflog message as the scripted version of rebase
-i when finishing. With this commit, we do that also for all the commands
before that.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/sequencer.c b/sequencer.c
index 0d8e11f580..95ae4bcd1e 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -1785,6 +1785,10 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
unlink(rebase_path_amend());
}
if (item->command <= TODO_SQUASH) {
+ if (is_rebase_i(opts))
+ setenv("GIT_REFLOG_ACTION", reflog_message(opts,
+ command_to_string(item->command), NULL),
+ 1);
res = do_pick_commit(item->command, item->commit,
opts, is_final_fixup(todo_list));
if (item->command == TODO_EDIT) {
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH v3 25/38] sequencer (rebase -i): run the post-rewrite hook, if needed
From: Johannes Schindelin @ 2017-01-02 15:28 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/sequencer.c b/sequencer.c
index d7273fd1b3..43ced8db31 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -1957,6 +1957,8 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
if (!stat(rebase_path_rewritten_list(), &st) &&
st.st_size > 0) {
struct child_process child = CHILD_PROCESS_INIT;
+ const char *post_rewrite_hook =
+ find_hook("post-rewrite");
child.in = open(rebase_path_rewritten_list(), O_RDONLY);
child.git_cmd = 1;
@@ -1965,6 +1967,18 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
argv_array_push(&child.args, "--for-rewrite=rebase");
/* we don't care if this copying failed */
run_command(&child);
+
+ if (post_rewrite_hook) {
+ struct child_process hook = CHILD_PROCESS_INIT;
+
+ hook.in = open(rebase_path_rewritten_list(),
+ O_RDONLY);
+ hook.stdout_to_stderr = 1;
+ argv_array_push(&hook.args, post_rewrite_hook);
+ argv_array_push(&hook.args, "rebase");
+ /* we don't care if this hook failed */
+ run_command(&hook);
+ }
}
strbuf_release(&buf);
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH v3 24/38] sequencer (rebase -i): record interrupted commits in rewritten, too
From: Johannes Schindelin @ 2017-01-02 15:28 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
When continuing after a `pick` command failed, we want that commit
to show up in the rewritten-list (and its notes to be rewritten), too.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/sequencer.c b/sequencer.c
index 50380a15b8..d7273fd1b3 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -2060,6 +2060,14 @@ int sequencer_continue(struct replay_opts *opts)
goto release_todo_list;
}
todo_list.current++;
+ } else if (file_exists(rebase_path_stopped_sha())) {
+ struct strbuf buf = STRBUF_INIT;
+ struct object_id oid;
+
+ if (read_oneliner(&buf, rebase_path_stopped_sha(), 1) &&
+ !get_sha1_committish(buf.buf, oid.hash))
+ record_in_rewritten(&oid, peek_command(&todo_list, 0));
+ strbuf_release(&buf);
}
res = pick_commits(&todo_list, opts);
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH v3 20/38] sequencer (rebase -i): allow fast-forwarding for edit/reword
From: Johannes Schindelin @ 2017-01-02 15:28 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
The sequencer already knew how to fast-forward instead of
cherry-picking, if possible.
We want to continue to do this, of course, but in case of the 'reword'
command, we will need to call `git commit` after fast-forwarding.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index 50e998acc4..23161f593e 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -860,7 +860,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
const char *base_label, *next_label;
struct commit_message msg = { NULL, NULL, NULL, NULL };
struct strbuf msgbuf = STRBUF_INIT;
- int res, unborn = 0, amend = 0, allow;
+ int res, unborn = 0, amend = 0, allow = 0;
if (opts->no_commit) {
/*
@@ -905,11 +905,23 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
else
parent = commit->parents->item;
+ if (get_message(commit, &msg) != 0)
+ return error(_("cannot get commit message for %s"),
+ oid_to_hex(&commit->object.oid));
+
if (opts->allow_ff && !is_fixup(command) &&
((parent && !hashcmp(parent->object.oid.hash, head)) ||
- (!parent && unborn)))
- return fast_forward_to(commit->object.oid.hash, head, unborn, opts);
-
+ (!parent && unborn))) {
+ if (is_rebase_i(opts))
+ write_author_script(msg.message);
+ res = fast_forward_to(commit->object.oid.hash, head, unborn,
+ opts);
+ if (res || command != TODO_REWORD)
+ goto leave;
+ edit = amend = 1;
+ msg_file = NULL;
+ goto fast_forward_edit;
+ }
if (parent && parse_commit(parent) < 0)
/* TRANSLATORS: The first %s will be a "todo" command like
"revert" or "pick", the second %s a SHA1. */
@@ -917,10 +929,6 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
command_to_string(command),
oid_to_hex(&parent->object.oid));
- if (get_message(commit, &msg) != 0)
- return error(_("cannot get commit message for %s"),
- oid_to_hex(&commit->object.oid));
-
/*
* "commit" is an existing commit. We would want to apply
* the difference it introduces since its first parent "prev"
@@ -1044,6 +1052,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
goto leave;
}
if (!opts->no_commit)
+fast_forward_edit:
res = run_git_commit(msg_file, opts, allow, edit, amend,
cleanup_commit_message);
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH v3 23/38] sequencer (rebase -i): copy commit notes at end
From: Johannes Schindelin @ 2017-01-02 15:28 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
When rebasing commits that have commit notes attached, the interactive
rebase rewrites those notes faithfully at the end. The sequencer must
do this, too, if it wishes to do interactive rebase's job.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/sequencer.c b/sequencer.c
index 95ae4bcd1e..50380a15b8 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -96,6 +96,15 @@ static GIT_PATH_FUNC(rebase_path_amend, "rebase-merge/amend")
*/
static GIT_PATH_FUNC(rebase_path_stopped_sha, "rebase-merge/stopped-sha")
/*
+ * For the post-rewrite hook, we make a list of rewritten commits and
+ * their new sha1s. The rewritten-pending list keeps the sha1s of
+ * commits that have been processed, but not committed yet,
+ * e.g. because they are waiting for a 'squash' command.
+ */
+static GIT_PATH_FUNC(rebase_path_rewritten_list, "rebase-merge/rewritten-list")
+static GIT_PATH_FUNC(rebase_path_rewritten_pending,
+ "rebase-merge/rewritten-pending")
+/*
* The following files are written by git-rebase just after parsing the
* command-line (and are only consumed, not modified, by the sequencer).
*/
@@ -850,6 +859,44 @@ static int update_squash_messages(enum todo_command command,
return res;
}
+static void flush_rewritten_pending(void) {
+ struct strbuf buf = STRBUF_INIT;
+ unsigned char newsha1[20];
+ FILE *out;
+
+ if (strbuf_read_file(&buf, rebase_path_rewritten_pending(), 82) > 0 &&
+ !get_sha1("HEAD", newsha1) &&
+ (out = fopen(rebase_path_rewritten_list(), "a"))) {
+ char *bol = buf.buf, *eol;
+
+ while (*bol) {
+ eol = strchrnul(bol, '\n');
+ fprintf(out, "%.*s %s\n", (int)(eol - bol),
+ bol, sha1_to_hex(newsha1));
+ if (!*eol)
+ break;
+ bol = eol + 1;
+ }
+ fclose(out);
+ unlink(rebase_path_rewritten_pending());
+ }
+ strbuf_release(&buf);
+}
+
+static void record_in_rewritten(struct object_id *oid,
+ enum todo_command next_command) {
+ FILE *out = fopen(rebase_path_rewritten_pending(), "a");
+
+ if (!out)
+ return;
+
+ fprintf(out, "%s\n", oid_to_hex(oid));
+ fclose(out);
+
+ if (!is_fixup(next_command))
+ flush_rewritten_pending();
+}
+
static int do_pick_commit(enum todo_command command, struct commit *commit,
struct replay_opts *opts, int final_fixup)
{
@@ -1743,6 +1790,17 @@ static int is_final_fixup(struct todo_list *todo_list)
return 1;
}
+static enum todo_command peek_command(struct todo_list *todo_list, int offset)
+{
+ int i;
+
+ for (i = todo_list->current + offset; i < todo_list->nr; i++)
+ if (!is_noop(todo_list->items[i].command))
+ return todo_list->items[i].command;
+
+ return -1;
+}
+
static const char *reflog_message(struct replay_opts *opts,
const char *sub_action, const char *fmt, ...)
{
@@ -1801,6 +1859,9 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
item->arg, item->arg_len, opts, res,
!res);
}
+ if (is_rebase_i(opts) && !res)
+ record_in_rewritten(&item->commit->object.oid,
+ peek_command(todo_list, 1));
if (res && is_fixup(item->command)) {
if (res == 1)
intend_to_amend();
@@ -1827,6 +1888,7 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
if (is_rebase_i(opts)) {
struct strbuf head_ref = STRBUF_INIT, buf = STRBUF_INIT;
+ struct stat st;
/* Stopped in the middle, as planned? */
if (todo_list->current < todo_list->nr)
@@ -1891,6 +1953,20 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
log_tree_diff_flush(&log_tree_opt);
}
}
+ flush_rewritten_pending();
+ if (!stat(rebase_path_rewritten_list(), &st) &&
+ st.st_size > 0) {
+ struct child_process child = CHILD_PROCESS_INIT;
+
+ child.in = open(rebase_path_rewritten_list(), O_RDONLY);
+ child.git_cmd = 1;
+ argv_array_push(&child.args, "notes");
+ argv_array_push(&child.args, "copy");
+ argv_array_push(&child.args, "--for-rewrite=rebase");
+ /* we don't care if this copying failed */
+ run_command(&child);
+ }
+
strbuf_release(&buf);
strbuf_release(&head_ref);
}
--
2.11.0.rc3.windows.1
^ permalink raw reply related
* [PATCH v3 21/38] sequencer (rebase -i): refactor setting the reflog message
From: Johannes Schindelin @ 2017-01-02 15:28 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Kevin Daudt, Dennis Kaarsemaker, Stephan Beyer,
Jeff King
In-Reply-To: <cover.1483370556.git.johannes.schindelin@gmx.de>
This makes the code DRYer, with the obvious benefit that we can enhance
the code further in a single place.
We can also reuse the functionality elsewhere by calling this new
function.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
sequencer.c | 33 ++++++++++++++++++++++++++-------
1 file changed, 26 insertions(+), 7 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index 23161f593e..0d8e11f580 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -1743,6 +1743,26 @@ static int is_final_fixup(struct todo_list *todo_list)
return 1;
}
+static const char *reflog_message(struct replay_opts *opts,
+ const char *sub_action, const char *fmt, ...)
+{
+ va_list ap;
+ static struct strbuf buf = STRBUF_INIT;
+
+ va_start(ap, fmt);
+ strbuf_reset(&buf);
+ strbuf_addstr(&buf, action_name(opts));
+ if (sub_action)
+ strbuf_addf(&buf, " (%s)", sub_action);
+ if (fmt) {
+ strbuf_addstr(&buf, ": ");
+ strbuf_vaddf(&buf, fmt, ap);
+ }
+ va_end(ap);
+
+ return buf.buf;
+}
+
static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
{
int res = 0;
@@ -1810,6 +1830,7 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
if (read_oneliner(&head_ref, rebase_path_head_name(), 0) &&
starts_with(head_ref.buf, "refs/")) {
+ const char *msg;
unsigned char head[20], orig[20];
int res;
@@ -1825,23 +1846,21 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
res = error(_("could not read orig-head"));
goto cleanup_head_ref;
}
- strbuf_addf(&buf, "rebase -i (finish): %s onto ",
- head_ref.buf);
if (!read_oneliner(&buf, rebase_path_onto(), 0)) {
res = error(_("could not read 'onto'"));
goto cleanup_head_ref;
}
- if (update_ref(buf.buf, head_ref.buf, head, orig,
+ msg = reflog_message(opts, "finish", "%s onto %s",
+ head_ref.buf, buf.buf);
+ if (update_ref(msg, head_ref.buf, head, orig,
REF_NODEREF, UPDATE_REFS_MSG_ON_ERR)) {
res = error(_("could not update %s"),
head_ref.buf);
goto cleanup_head_ref;
}
- strbuf_reset(&buf);
- strbuf_addf(&buf,
- "rebase -i (finish): returning to %s",
+ msg = reflog_message(opts, "finish", "returning to %s",
head_ref.buf);
- if (create_symref("HEAD", head_ref.buf, buf.buf)) {
+ if (create_symref("HEAD", head_ref.buf, msg)) {
res = error(_("could not update HEAD to %s"),
head_ref.buf);
goto cleanup_head_ref;
--
2.11.0.rc3.windows.1
^ 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