Git development
 help / color / mirror / Atom feed
* Re: en/rebase-merge-on-sequencer, was Re: What's cooking in git.git (Nov 2018, #07; Fri, 30)
From: Junio C Hamano @ 2018-11-30 14:13 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git
In-Reply-To: <nycvar.QRO.7.76.6.1811301429220.41@tvgsbejvaqbjf.bet>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> Hi Junio,
>
> On Fri, 30 Nov 2018, Junio C Hamano wrote:
>
>> * en/rebase-merge-on-sequencer (2018-11-08) 2 commits
>>  - rebase: implement --merge via git-rebase--interactive
>>  - git-rebase, sequencer: extend --quiet option for the interactive machinery
>> 
>>  "git rebase --merge" as been reimplemented by reusing the internal
>>  machinery used for "git rebase -i".
>
> I *think* a new iteration has landed (which has 7 instead of 2 commits):
> https://public-inbox.org/git/20181122044841.20993-1-newren@gmail.com/

"Landed" as opposed to "be in-flight"?  

You got me worried by implying that I merged them to either 'master'
or 'next' where it is harder to back out ;-).

During the freeze, especially after -rc1, I stop paying attention to
anything other than regression fixes and fixes to the addition since
the previous releases, unless I have too much time and get bored and
the new topic is trivial (which often means a single patch).

I'll mark the topic with the following, and continue ignoring it (or
any other topics) for now.  Thanks.

* en/rebase-merge-on-sequencer (2018-11-08) 2 commits
 - rebase: implement --merge via git-rebase--interactive
 - git-rebase, sequencer: extend --quiet option for the interactive machinery

 "git rebase --merge" as been reimplemented by reusing the internal
 machinery used for "git rebase -i".

 Reroll exists.
 cf. <20181122044841.20993-1-newren@gmail.com>



^ permalink raw reply

* Re: en/rebase-merge-on-sequencer, was Re: What's cooking in git.git (Nov 2018, #07; Fri, 30)
From: Johannes Schindelin @ 2018-11-30 15:22 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <xmqqpnumk604.fsf@gitster-ct.c.googlers.com>

Hi Junio,

On Fri, 30 Nov 2018, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > On Fri, 30 Nov 2018, Junio C Hamano wrote:
> >
> >> * en/rebase-merge-on-sequencer (2018-11-08) 2 commits
> >>  - rebase: implement --merge via git-rebase--interactive
> >>  - git-rebase, sequencer: extend --quiet option for the interactive machinery
> >> 
> >>  "git rebase --merge" as been reimplemented by reusing the internal
> >>  machinery used for "git rebase -i".
> >
> > I *think* a new iteration has landed (which has 7 instead of 2 commits):
> > https://public-inbox.org/git/20181122044841.20993-1-newren@gmail.com/
> 
> "Landed" as opposed to "be in-flight"?  
> 
> You got me worried by implying that I merged them to either 'master'
> or 'next' where it is harder to back out ;-).
> 
> During the freeze, especially after -rc1, I stop paying attention to
> anything other than regression fixes and fixes to the addition since
> the previous releases, unless I have too much time and get bored and
> the new topic is trivial (which often means a single patch).

I thought so, but then I thought I had seen you commenting on the
(distinctly non-single patch distinctly non-regression fix)
`split-checkout-into-two-new-commands` patch series ;-)

> I'll mark the topic with the following, and continue ignoring it (or
> any other topics) for now.  Thanks.
> 
> * en/rebase-merge-on-sequencer (2018-11-08) 2 commits
>  - rebase: implement --merge via git-rebase--interactive
>  - git-rebase, sequencer: extend --quiet option for the interactive machinery
> 
>  "git rebase --merge" as been reimplemented by reusing the internal
>  machinery used for "git rebase -i".
> 
>  Reroll exists.
>  cf. <20181122044841.20993-1-newren@gmail.com>

Thank you, much appreciated.
Dscho

^ permalink raw reply

* Re: en/rebase-merge-on-sequencer, was Re: What's cooking in git.git (Nov 2018, #07; Fri, 30)
From: Elijah Newren @ 2018-11-30 15:49 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, Git Mailing List
In-Reply-To: <xmqqpnumk604.fsf@gitster-ct.c.googlers.com>

On Fri, Nov 30, 2018 at 6:16 AM Junio C Hamano <gitster@pobox.com> wrote:
>
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> > Hi Junio,
> >
> > On Fri, 30 Nov 2018, Junio C Hamano wrote:
> >
> >> * en/rebase-merge-on-sequencer (2018-11-08) 2 commits
> >>  - rebase: implement --merge via git-rebase--interactive
> >>  - git-rebase, sequencer: extend --quiet option for the interactive machinery
> >>
> >>  "git rebase --merge" as been reimplemented by reusing the internal
> >>  machinery used for "git rebase -i".
> >
> > I *think* a new iteration has landed (which has 7 instead of 2 commits):
> > https://public-inbox.org/git/20181122044841.20993-1-newren@gmail.com/
>
> "Landed" as opposed to "be in-flight"?
>
> You got me worried by implying that I merged them to either 'master'
> or 'next' where it is harder to back out ;-).
>
> During the freeze, especially after -rc1, I stop paying attention to
> anything other than regression fixes and fixes to the addition since
> the previous releases, unless I have too much time and get bored and
> the new topic is trivial (which often means a single patch).
>
> I'll mark the topic with the following, and continue ignoring it (or
> any other topics) for now.  Thanks.
>
> * en/rebase-merge-on-sequencer (2018-11-08) 2 commits
>  - rebase: implement --merge via git-rebase--interactive
>  - git-rebase, sequencer: extend --quiet option for the interactive machinery
>
>  "git rebase --merge" as been reimplemented by reusing the internal
>  machinery used for "git rebase -i".
>
>  Reroll exists.
>  cf. <20181122044841.20993-1-newren@gmail.com>

I've also got a reroll with an extra patch to address Duy's feedback,
an extra patch to make a small documentation clarification/correction,
and a fix to a typo in a commit message from the last roll.  But I'm
waiting for 2.20.0 to be released before sending it.

^ permalink raw reply

* Re: [PATCH 3/5] pack-objects: add --sparse option
From: Derrick Stolee @ 2018-11-30 15:53 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Stefan Beller, gitgitgadget, git, Jeff King,
	Ævar Arnfjörð Bjarmason, Jonathan Nieder,
	Derrick Stolee
In-Reply-To: <xmqq36rjmgqf.fsf@gitster-ct.c.googlers.com>

On 11/29/2018 9:39 PM, Junio C Hamano wrote:
> Derrick Stolee <stolee@gmail.com> writes:
>
>> While _eventually_ we should make this opt-out, we shouldn't do that
>> until it has cooked a while.
> I actually do not agree.  If the knob gives enough benefit, the
> users will learn about it viva voce, and in a few more releases
> we'll hear "enough users complain that they have to turn it on,
> let's make it the default".  If that does not happen, the knob
> does not deserve to be turned on in the first place.

That's a good philosophy. I'll keep it in mind.
> Having said that, I won't be commenting on this shiny new toy before
> the final.  I want to see more people help tying the loose ends and
> give it final varnish to the upcoming release, as it seems to have
> become rockier and larger release than we originally anticipated.

Yeah, no rush on this one. I just wanted to get some initial feedback 
about the idea.

Thanks,
-Stolee

^ permalink raw reply

* Re: [PATCH v3 06/16] sequencer: refactor sequencer_add_exec_commands() to work on a todo_list
From: Phillip Wood @ 2018-11-30 17:02 UTC (permalink / raw)
  To: Alban Gruin, git; +Cc: Johannes Schindelin, Junio C Hamano
In-Reply-To: <20181109080805.6350-7-alban.gruin@gmail.com>

Hi Alban

Sorry it has taken me a while to look at the latest iteration. I like
the changes to pass a list of strings for the exec commands. I've only
had a chance to take a quick look, but I've got a couple of comments below

On 09/11/2018 08:07, Alban Gruin wrote:
> This refactors sequencer_add_exec_commands() to work on a todo_list to
> avoid redundant reads and writes to the disk.
> 
> Instead of just inserting the `exec' command between the other commands,
> and re-parsing the buffer at the end the exec command is appended to the
> buffer once, and a new list of items is created.  Items from the old
> list are copied across and new `exec' items are appended when
> necessary.  This eliminates the need to reparse the buffer, but this
> also means we have to use todo_list_write_to_disk() to write the file().
> 
> todo_list_add_exec_commands() and sequencer_add_exec_commands() are
> modified to take a string list instead of a string -- one item for each
> command.  This makes it easier to insert a new command to the todo list
> for each command to execute.
> 
> sequencer_add_exec_commands() still reads the todo list from the disk,
> as it is needed by rebase -p.
> 
> complete_action() still uses sequencer_add_exec_commands() for now.
> This will be changed in a future commit.
> 
> Signed-off-by: Alban Gruin <alban.gruin@gmail.com>
> ---
>  builtin/rebase--interactive.c |  15 +++--
>  sequencer.c                   | 111 +++++++++++++++++++++-------------
>  sequencer.h                   |   4 +-
>  3 files changed, 83 insertions(+), 47 deletions(-)
> 
> diff --git a/builtin/rebase--interactive.c b/builtin/rebase--interactive.c
> index c1d87c0fe6..1fb5a43c0d 100644
> --- a/builtin/rebase--interactive.c
> +++ b/builtin/rebase--interactive.c
> @@ -65,7 +65,7 @@ static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
>  				 const char *onto, const char *onto_name,
>  				 const char *squash_onto, const char *head_name,
>  				 const char *restrict_revision, char *raw_strategies,
> -				 const char *cmd, unsigned autosquash)
> +				 struct string_list *commands, unsigned autosquash)
>  {
>  	int ret;
>  	const char *head_hash = NULL;
> @@ -115,7 +115,7 @@ static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
>  	else {
>  		discard_cache();
>  		ret = complete_action(opts, flags, shortrevisions, onto_name, onto,
> -				      head_hash, cmd, autosquash);
> +				      head_hash, commands, autosquash);
>  	}
>  
>  	free(revisions);
> @@ -138,6 +138,7 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
>  	const char *onto = NULL, *onto_name = NULL, *restrict_revision = NULL,
>  		*squash_onto = NULL, *upstream = NULL, *head_name = NULL,
>  		*switch_to = NULL, *cmd = NULL;
> +	struct string_list commands = STRING_LIST_INIT_DUP;
>  	char *raw_strategies = NULL;
>  	enum {
>  		NONE = 0, CONTINUE, SKIP, EDIT_TODO, SHOW_CURRENT_PATCH,
> @@ -220,6 +221,12 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
>  		warning(_("--[no-]rebase-cousins has no effect without "
>  			  "--rebase-merges"));
>  
> +	if (cmd && *cmd) {
> +		string_list_split(&commands, cmd, '\n', -1);
> +		if (strlen(commands.items[commands.nr - 1].string) == 0)
> +			--commands.nr;
> +	}
> +
>  	switch (command) {
>  	case NONE:
>  		if (!onto && !upstream)
> @@ -227,7 +234,7 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
>  
>  		ret = do_interactive_rebase(&opts, flags, switch_to, upstream, onto,
>  					    onto_name, squash_onto, head_name, restrict_revision,
> -					    raw_strategies, cmd, autosquash);
> +					    raw_strategies, &commands, autosquash);
>  		break;
>  	case SKIP: {
>  		struct string_list merge_rr = STRING_LIST_INIT_DUP;
> @@ -261,7 +268,7 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
>  		ret = rearrange_squash();
>  		break;
>  	case ADD_EXEC:
> -		ret = sequencer_add_exec_commands(cmd);
> +		ret = sequencer_add_exec_commands(&commands);
>  		break;
>  	default:
>  		BUG("invalid command '%d'", command);
> diff --git a/sequencer.c b/sequencer.c
> index 900899ef20..11692d0b98 100644
> --- a/sequencer.c
> +++ b/sequencer.c
> @@ -4394,24 +4394,29 @@ int sequencer_make_script(FILE *out, int argc, const char **argv,
>  	return 0;
>  }
>  
> -/*
> - * Add commands after pick and (series of) squash/fixup commands
> - * in the todo list.
> - */
> -int sequencer_add_exec_commands(const char *commands)
> +static void todo_list_add_exec_commands(struct todo_list *todo_list,
> +					struct string_list *commands)
>  {
> -	const char *todo_file = rebase_path_todo();
> -	struct todo_list todo_list = TODO_LIST_INIT;
> -	struct strbuf *buf = &todo_list.buf;
> -	size_t offset = 0, commands_len = strlen(commands);
> -	int i, insert;
> +	struct strbuf *buf = &todo_list->buf;
> +	const char *old_buf = buf->buf;
> +	size_t base_length = buf->len;
> +	int i, insert, nr = 0, alloc = 0;
> +	struct todo_item *items = NULL, *base_items = NULL;
>  
> -	if (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)
> -		return error(_("could not read '%s'."), todo_file);
> +	for (i = 0; i < commands->nr; ++i) {
> +		strbuf_addstr(buf, commands->items[i].string);
> +		strbuf_addch(buf, '\n');
> +	}

This could cause buf->buf to be reallocated in which case all the 
todo_list_item.arg pointers will be invalidated. I think you want to 
covert all those pointers to offsets stored in a temporary array and 
then recreate the correct pointers from the offsets after appending to buf.

> -	if (todo_list_parse_insn_buffer(todo_list.buf.buf, &todo_list)) {
> -		todo_list_release(&todo_list);
> -		return error(_("unusable todo list: '%s'"), todo_file);
> +	base_items = xcalloc(commands->nr, sizeof(struct todo_item));
> +	for (i = 0; i < commands->nr; ++i) {
> +		size_t command_len = strlen(commands->items[i].string) - strlen("exec ");
> +
> +		base_items[i].command = TODO_EXEC;
> +		base_items[i].offset_in_buf = base_length + strlen("exec ");

Currently parse_insn_buffer() sets offset_in_buf to the beginning of the
line, it does not skip the command name I think it would be good to keep 
this consistent with all the other commands.

> +		base_items[i].arg = buf->buf + base_items[i].offset_in_buf;
> +		base_items[i].arg_len = command_len;
> +		base_length = base_items[i].offset_in_buf + base_items[i].arg_len + 1;

base_length is actually on offset into the buffer, it took me a while to 
figure out that the calculation is correct. It might be simpler to do

base_offset += strlen(commands->items[i].string) + 1;

>  	}
>  
>  	/*
> @@ -4420,38 +4425,62 @@ int sequencer_add_exec_commands(const char *commands)
>  	 * those chains if there are any.
>  	 */
>  	insert = -1;
> -	for (i = 0; i < todo_list.nr; i++) {
> -		enum todo_command command = todo_list.items[i].command;
> -
> -		if (insert >= 0) {
> -			/* skip fixup/squash chains */
> -			if (command == TODO_COMMENT)
> -				continue;
> -			else if (is_fixup(command)) {
> -				insert = i + 1;
> -				continue;
> -			}
> -			strbuf_insert(buf,
> -				      todo_list.items[insert].offset_in_buf +
> -				      offset, commands, commands_len);
> -			offset += commands_len;
> +	for (i = 0; i < todo_list->nr; i++) {
> +		enum todo_command command = todo_list->items[i].command;
> +		if (todo_list->items[i].arg)
> +			todo_list->items[i].arg = todo_list->items[i].arg - old_buf + buf->buf;

I think that is undefined behavior the old value of a pointer passed 
realloc() is undefined so cannot be used for pointer arithmetic. Using a 
temporary array of offsets as suggested above would avoid this.

Best Wishes

Phillip

> +
> +		if (insert >= 0 && command != TODO_COMMENT && !is_fixup(command)) {
> +			ALLOC_GROW(items, nr + commands->nr, alloc);
> +			COPY_ARRAY(items + nr, base_items, commands->nr);
> +			nr += commands->nr;
>  			insert = -1;
>  		}
>  
> -		if (command == TODO_PICK || command == TODO_MERGE)
> +		ALLOC_GROW(items, nr + 1, alloc);
> +		items[nr++] = todo_list->items[i];
> +
> +		if (command == TODO_PICK || command == TODO_MERGE || is_fixup(command))
>  			insert = i + 1;
>  	}
>  
>  	/* insert or append final <commands> */
> -	if (insert >= 0 && insert < todo_list.nr)
> -		strbuf_insert(buf, todo_list.items[insert].offset_in_buf +
> -			      offset, commands, commands_len);
> -	else if (insert >= 0 || !offset)
> -		strbuf_add(buf, commands, commands_len);
> +	if (insert >= 0 || nr == todo_list->nr) {
> +		ALLOC_GROW(items, nr + commands->nr, alloc);
> +		COPY_ARRAY(items + nr, base_items, commands->nr);
> +		nr += commands->nr;
> +	}
> +
> +	free(base_items);
> +	FREE_AND_NULL(todo_list->items);
> +	todo_list->items = items;
> +	todo_list->nr = nr;
> +	todo_list->alloc = alloc;
> +}
> +
> +/*
> + * Add commands after pick and (series of) squash/fixup commands
> + * in the todo list.
> + */
> +int sequencer_add_exec_commands(struct string_list *commands)
> +{
> +	const char *todo_file = rebase_path_todo();
> +	struct todo_list todo_list = TODO_LIST_INIT;
> +	int res;
>  
> -	i = write_message(buf->buf, buf->len, todo_file, 0);
> +	if (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)
> +		return error(_("could not read '%s'."), todo_file);
> +
> +	if (todo_list_parse_insn_buffer(todo_list.buf.buf, &todo_list)) {
> +		todo_list_release(&todo_list);
> +		return error(_("unusable todo list: '%s'"), todo_file);
> +	}
> +
> +	todo_list_add_exec_commands(&todo_list, commands);
> +	res = todo_list_write_to_file(&todo_list, todo_file, NULL, NULL, -1, 0);
>  	todo_list_release(&todo_list);
> -	return i;
> +
> +	return res;
>  }
>  
>  static void todo_list_to_strbuf(struct todo_list *todo_list, struct strbuf *buf,
> @@ -4677,7 +4706,7 @@ static int skip_unnecessary_picks(struct object_id *output_oid)
>  
>  int complete_action(struct replay_opts *opts, unsigned flags,
>  		    const char *shortrevisions, const char *onto_name,
> -		    const char *onto, const char *orig_head, const char *cmd,
> +		    const char *onto, const char *orig_head, struct string_list *commands,
>  		    unsigned autosquash)
>  {
>  	const char *shortonto, *todo_file = rebase_path_todo();
> @@ -4696,8 +4725,8 @@ int complete_action(struct replay_opts *opts, unsigned flags,
>  	if (autosquash && rearrange_squash())
>  		return -1;
>  
> -	if (cmd && *cmd)
> -		sequencer_add_exec_commands(cmd);
> +	if (commands->nr)
> +		sequencer_add_exec_commands(commands);
>  
>  	if (strbuf_read_file(buf, todo_file, 0) < 0)
>  		return error_errno(_("could not read '%s'."), todo_file);
> diff --git a/sequencer.h b/sequencer.h
> index c78f00aadd..d7b52044bd 100644
> --- a/sequencer.h
> +++ b/sequencer.h
> @@ -140,12 +140,12 @@ int sequencer_remove_state(struct replay_opts *opts);
>  int sequencer_make_script(FILE *out, int argc, const char **argv,
>  			  unsigned flags);
>  
> -int sequencer_add_exec_commands(const char *command);
> +int sequencer_add_exec_commands(struct string_list *commands);
>  int transform_todo_file(unsigned flags);
>  int check_todo_list_from_file(void);
>  int complete_action(struct replay_opts *opts, unsigned flags,
>  		    const char *shortrevisions, const char *onto_name,
> -		    const char *onto, const char *orig_head, const char *cmd,
> +		    const char *onto, const char *orig_head, struct string_list *commands,
>  		    unsigned autosquash);
>  int rearrange_squash(void);
>  
> 


^ permalink raw reply

* [PATCH] l10n: update German translation
From: Ralf Thielow @ 2018-11-30 17:35 UTC (permalink / raw)
  To: git; +Cc: Matthias Rüster, Phillip Szelat, Ralf Thielow

Signed-off-by: Ralf Thielow <ralf.thielow@gmail.com>
---
 po/de.po | 827 +++++++++++++++++++++++++------------------------------
 1 file changed, 375 insertions(+), 452 deletions(-)

diff --git a/po/de.po b/po/de.po
index 3cf9405df..256b668a8 100644
--- a/po/de.po
+++ b/po/de.po
@@ -943,17 +943,17 @@ msgid ""
 "Use '\\!' for literal leading exclamation."
 msgstr ""
 "Verneinende Muster werden in Git-Attributen ignoriert.\n"
 "Benutzen Sie '\\!' für führende Ausrufezeichen."
 
 #: bisect.c:468
 #, c-format
 msgid "Badly quoted content in file '%s': %s"
-msgstr "Ungültiger Inhalt bzgl. Anführungsstriche in Datei '%s': %s"
+msgstr "Ungültiger Inhalt bzgl. Anführungszeichen in Datei '%s': %s"
 
 #: bisect.c:676
 #, c-format
 msgid "We cannot bisect more!\n"
 msgstr "Keine binäre Suche mehr möglich!\n"
 
 #: bisect.c:730
 #, c-format
@@ -1282,19 +1282,18 @@ msgstr "Das Paket speichert eine komplette Historie."
 #: bundle.c:201
 #, c-format
 msgid "The bundle requires this ref:"
 msgid_plural "The bundle requires these %d refs:"
 msgstr[0] "Das Paket benötigt diese Referenz:"
 msgstr[1] "Das Paket benötigt diese %d Referenzen:"
 
 #: bundle.c:267
-#, fuzzy
 msgid "unable to dup bundle descriptor"
-msgstr "Konnte Descriptor nicht umleiten."
+msgstr "Konnte dup für Descriptor des Pakets nicht ausführen."
 
 #: bundle.c:274
 msgid "Could not spawn pack-objects"
 msgstr "Konnte Paketobjekte nicht erstellen"
 
 #: bundle.c:285
 msgid "pack-objects died"
 msgstr "Erstellung der Paketobjekte abgebrochen"
@@ -1433,28 +1432,26 @@ msgid "could not find commit %s"
 msgstr "Konnte Commit %s nicht finden."
 
 #: commit-graph.c:617 builtin/pack-objects.c:2652
 #, c-format
 msgid "unable to get type of object %s"
 msgstr "Konnte Art von Objekt '%s' nicht bestimmen."
 
 #: commit-graph.c:651
-#, fuzzy
 msgid "Annotating commits in commit graph"
-msgstr "Zu viele Commits zum Schreiben des Graphen."
+msgstr "Annotiere Commits in Commit-Graphen"
 
 #: commit-graph.c:691
 msgid "Computing commit graph generation numbers"
-msgstr ""
+msgstr "Commit-Graph Generierungsnummern berechnen"
 
 #: commit-graph.c:803 commit-graph.c:826 commit-graph.c:852
-#, fuzzy
 msgid "Finding commits for commit graph"
-msgstr "Zu viele Commits zum Schreiben des Graphen."
+msgstr "Bestimme Commits für Commit-Graphen"
 
 #: commit-graph.c:812
 #, c-format
 msgid "error adding pack %s"
 msgstr "Fehler beim Hinzufügen von Paket %s."
 
 #: commit-graph.c:814
 #, c-format
@@ -1478,17 +1475,17 @@ msgstr "Konnte führende Verzeichnisse von '%s' nicht erstellen."
 #: commit-graph.c:1002
 msgid "the commit-graph file has incorrect checksum and is likely corrupt"
 msgstr ""
 "Die Commit-Graph-Datei hat eine falsche Prüfsumme und ist wahrscheinlich "
 "beschädigt."
 
 #: commit-graph.c:1046
 msgid "Verifying commits in commit graph"
-msgstr ""
+msgstr "Commit in Commit-Graph überprüfen"
 
 #: compat/obstack.c:405 compat/obstack.c:407
 msgid "memory exhausted"
 msgstr "Speicher verbraucht"
 
 #: config.c:123
 #, c-format
 msgid ""
@@ -2193,37 +2190,39 @@ msgstr[1] "%s, und %<PRIuMAX> Monaten"
 #, c-format
 msgid "%<PRIuMAX> year ago"
 msgid_plural "%<PRIuMAX> years ago"
 msgstr[0] "vor %<PRIuMAX> Jahr"
 msgstr[1] "vor %<PRIuMAX> Jahren"
 
 #: delta-islands.c:268
 msgid "Propagating island marks"
-msgstr ""
+msgstr "Erzeuge Delta-Island Markierungen"
 
 #: delta-islands.c:286
-#, fuzzy, c-format
+#, c-format
 msgid "bad tree object %s"
-msgstr "Konnte Objekt %s nicht lesen."
+msgstr "Ungültiges Tree-Objekt %s."
 
 #: delta-islands.c:330
-#, fuzzy, c-format
+#, c-format
 msgid "failed to load island regex for '%s': %s"
-msgstr "Fehler beim Finden des \"Tree\"-Objektes von %s."
+msgstr "Fehler beim Laden des regulären Ausdrucks des Delta-Island für '%s': %s"
 
 #: delta-islands.c:386
 #, c-format
 msgid "island regex from config has too many capture groups (max=%d)"
 msgstr ""
+"Regulärer Ausdruck des Delta-Island aus Konfiguration hat zu\n"
+"viele Capture-Gruppen (maximal %d)."
 
 #: delta-islands.c:462
 #, c-format
 msgid "Marked %d islands, done.\n"
-msgstr ""
+msgstr "%d Delta-Islands markiert, fertig.\n"
 
 #: diffcore-order.c:24
 #, c-format
 msgid "failed to read orderfile '%s'"
 msgstr "Fehler beim Lesen der Reihenfolgedatei '%s'."
 
 #: diffcore-rename.c:544
 msgid "Performing inexact rename detection"
@@ -2592,21 +2591,21 @@ msgstr "Unerwartete Acknowledgment-Zeile: '%s'"
 
 #: fetch-pack.c:1249
 #, c-format
 msgid "error processing acks: %d"
 msgstr "Fehler beim Verarbeiten von ACKS: %d"
 
 #: fetch-pack.c:1259
 msgid "expected packfile to be sent after 'ready'"
-msgstr ""
+msgstr "Erwartete Versand einer Packdatei nach 'ready'."
 
 #: fetch-pack.c:1261
 msgid "expected no other sections to be sent after no 'ready'"
-msgstr ""
+msgstr "Erwartete keinen Versand einer anderen Sektion ohne 'ready'."
 
 #: fetch-pack.c:1298
 #, c-format
 msgid "error processing shallow info: %d"
 msgstr "Fehler beim Verarbeiten von Shallow-Informationen: %d"
 
 #: fetch-pack.c:1314
 #, c-format
@@ -2746,26 +2745,25 @@ msgid "unsupported command listing type '%s'"
 msgstr "Nicht unterstützte Art zur Befehlsauflistung '%s'."
 
 #: help.c:408
 msgid "The common Git guides are:"
 msgstr "Die allgemeinen Git-Anleitungen sind:"
 
 #: help.c:517
 msgid "See 'git help <command>' to read about a specific subcommand"
-msgstr ""
+msgstr "Siehe 'git help <Befehl>', um mehr über einen spezifischen Unterbefehl zu lesen."
 
 #: help.c:522
-#, fuzzy
 msgid "External commands"
-msgstr "führe $command aus"
+msgstr "Externe Befehle"
 
 #: help.c:530
 msgid "Command aliases"
-msgstr ""
+msgstr "Alias-Befehle"
 
 #: help.c:594
 #, c-format
 msgid ""
 "'%s' appears to be a git command, but we were not\n"
 "able to execute it. Maybe git-%s is broken?"
 msgstr ""
 "'%s' scheint ein git-Befehl zu sein, konnte aber\n"
@@ -2892,19 +2890,18 @@ msgstr "Name besteht nur aus nicht erlaubten Zeichen: %s"
 msgid "invalid date format: %s"
 msgstr "Ungültiges Datumsformat: %s"
 
 #: list-objects-filter-options.c:35
 msgid "multiple filter-specs cannot be combined"
 msgstr "Mehrere filter-specs können nicht kombiniert werden."
 
 #: list-objects-filter-options.c:58
-#, fuzzy
 msgid "only 'tree:0' is supported"
-msgstr "Protokoll '%s' wird nicht unterstützt."
+msgstr "Es wird nur 'tree:0' unterstützt."
 
 #: list-objects-filter-options.c:137
 msgid "cannot change partial clone promisor remote"
 msgstr "Kann Remote-Repository für partielles Klonen nicht ändern."
 
 #: lockfile.c:151
 #, c-format
 msgid ""
@@ -3355,142 +3352,141 @@ msgstr "Merge hat keinen Commit zurückgegeben"
 msgid "Could not parse object '%s'"
 msgstr "Konnte Objekt '%s' nicht parsen."
 
 #: merge-recursive.c:3553 builtin/merge.c:691 builtin/merge.c:849
 msgid "Unable to write index."
 msgstr "Konnte Index nicht schreiben."
 
 #: midx.c:65
-#, fuzzy, c-format
+#, c-format
 msgid "multi-pack-index file %s is too small"
-msgstr "Graph-Datei %s ist zu klein."
+msgstr "multi-pack-index-Datei %s ist zu klein."
 
 #: midx.c:81
-#, fuzzy, c-format
+#, c-format
 msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x"
-msgstr "Graph-Signatur %X stimmt nicht mit Signatur %X überein."
+msgstr "multi-pack-index-Signatur 0x%08x stimmt nicht mit Signatur 0x%08x überein."
 
 #: midx.c:86
 #, c-format
 msgid "multi-pack-index version %d not recognized"
-msgstr ""
+msgstr "multi-pack-index-Version %d nicht erkannt."
 
 #: midx.c:91
-#, fuzzy, c-format
+#, c-format
 msgid "hash version %u does not match"
-msgstr "Hash-Version %X stimmt nicht mit Version %X überein."
+msgstr "Hash-Version %u stimmt nicht überein."
 
 #: midx.c:105
 msgid "invalid chunk offset (too large)"
-msgstr ""
+msgstr "Ungültiger Chunk-Offset (zu groß)"
 
 #: midx.c:129
 msgid "terminating multi-pack-index chunk id appears earlier than expected"
-msgstr ""
+msgstr "Abschließende multi-pack-index Chunk-Id erscheint eher als erwartet."
 
 #: midx.c:142
 msgid "multi-pack-index missing required pack-name chunk"
-msgstr ""
+msgstr "multi-pack-index fehlt erforderlicher pack-name Chunk."
 
 #: midx.c:144
 msgid "multi-pack-index missing required OID fanout chunk"
-msgstr ""
+msgstr "multi-pack-index fehlt erforderlicher OID fanout Chunk."
 
 #: midx.c:146
 msgid "multi-pack-index missing required OID lookup chunk"
-msgstr ""
+msgstr "multi-pack-index fehlt erforderlicher OID lookup Chunk."
 
 #: midx.c:148
 msgid "multi-pack-index missing required object offsets chunk"
-msgstr ""
+msgstr "multi-pack-index fehlt erforderlicher object offset Chunk."
 
 #: midx.c:162
 #, c-format
 msgid "multi-pack-index pack names out of order: '%s' before '%s'"
-msgstr ""
+msgstr "Falsche Reihenfolge bei multi-pack-index Pack-Namen: '%s' vor '%s'"
 
 #: midx.c:205
 #, c-format
 msgid "bad pack-int-id: %u (%u total packs"
-msgstr ""
+msgstr "Fehlerhafte pack-int-id: %u (%u Pakete insgesamt)"
 
 #: midx.c:246
 msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
-msgstr ""
+msgstr "multi-pack-index speichert einen 64-Bit Offset, aber off_t ist zu klein."
 
 #: midx.c:271
 msgid "error preparing packfile from multi-pack-index"
-msgstr ""
+msgstr "Fehler bei Vorbereitung der Packdatei aus multi-pack-index."
 
 #: midx.c:407
-#, fuzzy, c-format
+#, c-format
 msgid "failed to add packfile '%s'"
-msgstr "Fehler beim Lesen der Reihenfolgedatei '%s'."
+msgstr "Fehler beim Hinzufügen von Packdatei'%s'."
 
 #: midx.c:413
-#, fuzzy, c-format
+#, c-format
 msgid "failed to open pack-index '%s'"
-msgstr "Fehler beim Öffnen von '%s'"
+msgstr "Fehler beim Öffnen von pack-index '%s'"
 
 #: midx.c:507
-#, fuzzy, c-format
+#, c-format
 msgid "failed to locate object %d in packfile"
-msgstr "Konnte Objekt %s nicht lesen."
+msgstr "Fehler beim Lokalisieren von Objekt %d in Packdatei."
 
 #: midx.c:943
-#, fuzzy, c-format
+#, c-format
 msgid "failed to clear multi-pack-index at %s"
-msgstr "Fehler beim Bereinigen des Index"
+msgstr "Fehler beim Löschen des multi-pack-index bei %s"
 
 #: midx.c:981
 #, c-format
 msgid ""
 "oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
-msgstr ""
+msgstr "Ungültige oid fanout Reihenfolge: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
 
 #: midx.c:992
 #, c-format
 msgid "oid lookup out of order: oid[%d] = %s >= %s = oid[%d]"
-msgstr ""
+msgstr "Ungültige oid lookup Reihenfolge: oid[%d] = %s >= %s = oid[%d]"
 
 #: midx.c:996
-#, fuzzy
 msgid "Verifying object offsets"
-msgstr "Schreibe Objekte"
+msgstr "Überprüfe Objekt-Offsets"
 
 #: midx.c:1004
-#, fuzzy, c-format
+#, c-format
 msgid "failed to load pack entry for oid[%d] = %s"
-msgstr "kann für %s keinen Eintrag in den Zwischenspeicher hinzufügen"
+msgstr "Fehler beim Laden des Pack-Eintrags für oid[%d] = %s"
 
 #: midx.c:1010
-#, fuzzy, c-format
+#, c-format
 msgid "failed to load pack-index for packfile %s"
-msgstr "Fehler beim Lesen der Reihenfolgedatei '%s'."
+msgstr "Fehler beim Laden des Pack-Index für Packdatei %s"
 
 #: midx.c:1019
 #, c-format
 msgid "incorrect object offset for oid[%d] = %s: %<PRIx64> != %<PRIx64>"
-msgstr ""
+msgstr "Falscher Objekt-Offset für oid[%d] = %s: %<PRIx64> != %<PRIx64>"
 
 #: name-hash.c:532
-#, fuzzy, c-format
+#, c-format
 msgid "unable to create lazy_dir thread: %s"
-msgstr "kann Thread nicht erzeugen: %s"
+msgstr "Kann lazy_dir Thread nicht erzeugen: %s"
 
 #: name-hash.c:554
-#, fuzzy, c-format
+#, c-format
 msgid "unable to create lazy_name thread: %s"
-msgstr "kann Thread nicht erzeugen: %s"
+msgstr "Kann lazy_name Thread nicht erzeugen: %s"
 
 #: name-hash.c:560
-#, fuzzy, c-format
+#, c-format
 msgid "unable to join lazy_name thread: %s"
-msgstr "kann Thread nicht erzeugen: %s"
+msgstr "Kann lazy_name Thread nicht beitreten: %s"
 
 #: notes-merge.c:275
 #, c-format
 msgid ""
 "You have not concluded your previous notes merge (%s exists).\n"
 "Please, use 'git notes merge --commit' or 'git notes merge --abort' to "
 "commit/abort the previous merge before you start a new notes merge."
 msgstr ""
@@ -3723,24 +3719,23 @@ msgid "protocol error: bad line length character: %.4s"
 msgstr "Protokollfehler: ungültiges Zeichen für Zeilenlänge: %.4s"
 
 #: pkt-line.c:337 pkt-line.c:342
 #, c-format
 msgid "protocol error: bad line length %d"
 msgstr "Protokollfehler: ungültige Zeilenlänge %d"
 
 #: preload-index.c:118
-#, fuzzy
 msgid "Refreshing index"
-msgstr "Konnte den Index nicht aktualisieren."
+msgstr "Aktualisiere Index"
 
 #: preload-index.c:137
-#, fuzzy, c-format
+#, c-format
 msgid "unable to create threaded lstat: %s"
-msgstr "kann Thread nicht erzeugen: %s"
+msgstr "Kann Thread für lstat nicht erzeugen: %s"
 
 #: pretty.c:962
 msgid "unable to parse --pretty format"
 msgstr "Konnte --pretty Format nicht parsen."
 
 #: range-diff.c:56
 msgid "could not start `log`"
 msgstr "Konnte `log` nicht starten."
@@ -3759,19 +3754,18 @@ msgid "failed to generate diff"
 msgstr "Fehler beim Generieren des Diffs."
 
 #: range-diff.c:455 range-diff.c:457
 #, c-format
 msgid "could not parse log for '%s'"
 msgstr "Konnte Log für '%s' nicht parsen."
 
 #: read-cache.c:1490
-#, fuzzy
 msgid "Refresh index"
-msgstr "Konnte den Index nicht aktualisieren."
+msgstr "Aktualisiere Index"
 
 #: read-cache.c:1604
 #, c-format
 msgid ""
 "index.version set, but the value is invalid.\n"
 "Using version %i"
 msgstr ""
 "index.version gesetzt, aber Wert ungültig.\n"
@@ -3784,50 +3778,50 @@ msgid ""
 "Using version %i"
 msgstr ""
 "GIT_INDEX_VERSION gesetzt, aber Wert ungültig.\n"
 "Verwende Version %i"
 
 #: read-cache.c:1792
 #, c-format
 msgid "malformed name field in the index, near path '%s'"
-msgstr ""
+msgstr "Ungültiges Namensfeld im Index, in der Nähe von Pfad '%s'."
 
 #: read-cache.c:1960 rerere.c:565 rerere.c:599 rerere.c:1111 builtin/add.c:458
 #: builtin/check-ignore.c:177 builtin/checkout.c:289 builtin/checkout.c:585
 #: builtin/checkout.c:953 builtin/clean.c:954 builtin/commit.c:343
 #: builtin/diff-tree.c:115 builtin/grep.c:489 builtin/mv.c:144
 #: builtin/reset.c:244 builtin/rm.c:270 builtin/submodule--helper.c:329
 msgid "index file corrupt"
 msgstr "Index-Datei beschädigt"
 
 #: read-cache.c:2101
-#, fuzzy, c-format
+#, c-format
 msgid "unable to create load_cache_entries thread: %s"
-msgstr "kann Thread nicht erzeugen: %s"
+msgstr "Kann Thread für load_cache_entries nicht erzeugen: %s"
 
 #: read-cache.c:2114
-#, fuzzy, c-format
+#, c-format
 msgid "unable to join load_cache_entries thread: %s"
-msgstr "kann Thread nicht erzeugen: %s"
+msgstr "Kann Thread für load_cache_entries nicht erzeugen: %s"
 
 #: read-cache.c:2200
-#, fuzzy, c-format
+#, c-format
 msgid "unable to create load_index_extensions thread: %s"
-msgstr "kann Thread nicht erzeugen: %s"
+msgstr "Kann Thread für load_index_extensions nicht erzeugen: %s"
 
 #: read-cache.c:2227
-#, fuzzy, c-format
+#, c-format
 msgid "unable to join load_index_extensions thread: %s"
-msgstr "kann Thread nicht erzeugen: %s"
+msgstr "Kann Thread für load_index_extensions nicht erzeugen: %s"
 
 #: read-cache.c:2953 sequencer.c:4727 wrapper.c:658 builtin/merge.c:1086
 #, c-format
 msgid "could not close '%s'"
-msgstr "Konnte '%s' nicht schließen"
+msgstr "Konnte '%s' nicht schließen."
 
 #: read-cache.c:3026 sequencer.c:2203 sequencer.c:3592
 #, c-format
 msgid "could not stat '%s'"
 msgstr "Konnte '%s' nicht lesen."
 
 #: read-cache.c:3039
 #, c-format
@@ -3835,17 +3829,16 @@ msgid "unable to open git dir: %s"
 msgstr "konnte Git-Verzeichnis nicht öffnen: %s"
 
 #: read-cache.c:3051
 #, c-format
 msgid "unable to unlink: %s"
 msgstr "Konnte '%s' nicht entfernen."
 
 #: rebase-interactive.c:10
-#, fuzzy
 msgid ""
 "\n"
 "Commands:\n"
 "p, pick <commit> = use commit\n"
 "r, reword <commit> = use commit, but edit the commit message\n"
 "e, edit <commit> = use commit, but stop for amending\n"
 "s, squash <commit> = use commit, but meld into previous commit\n"
 "f, fixup <commit> = like \"squash\", but discard this commit's log message\n"
@@ -3862,26 +3855,25 @@ msgid ""
 "These lines can be re-ordered; they are executed from top to bottom.\n"
 msgstr ""
 "\n"
 "Befehle:\n"
 "p, pick <Commit> = Commit verwenden\n"
 "r, reword <Commit> = Commit verwenden, aber Commit-Beschreibung bearbeiten\n"
 "e, edit <Commit> = Commit verwenden, aber zum Nachbessern anhalten\n"
 "s, squash <Commit> = Commit verwenden, aber mit vorherigem Commit vereinen\n"
-"f, fixup <Commit> = wie \"squash\", aber diese Commit-Beschreibung "
-"verwerfen\n"
+"f, fixup <Commit> = wie \"squash\", aber diese Commit-Beschreibung verwerfen\n"
 "x, exec <Commit> = Befehl (Rest der Zeile) mittels Shell ausführen\n"
+"b, break = hier anhalten (Rebase später mit 'git rebase --continue' fortsetzen)\n"
 "d, drop <Commit> = Commit entfernen\n"
 "l, label <Label> = aktuellen HEAD mit Label versehen\n"
 "t, reset <Label> = HEAD zu einem Label umsetzen\n"
 "m, merge [-C <Commit> | -c <Commit>] <Label> [# <eineZeile>]\n"
 ".       Merge-Commit mit der originalen Merge-Commit-Beschreibung erstellen\n"
-".       (oder die eine Zeile, wenn keine originale Merge-Commit-"
-"Beschreibung\n"
+".       (oder die eine Zeile, wenn keine originale Merge-Commit-Beschreibung\n"
 ".       spezifiziert ist). Benutzen Sie -c <Commit> zum Bearbeiten der\n"
 ".       Commit-Beschreibung.\n"
 "\n"
 "Diese Zeilen können umsortiert werden; Sie werden von oben nach unten\n"
 "ausgeführt.\n"
 
 #: rebase-interactive.c:31 git-rebase--preserve-merges.sh:173
 msgid ""
@@ -4182,17 +4174,17 @@ msgstr "Fehlerhafter Feldname: %.*s"
 #, c-format
 msgid "unknown field name: %.*s"
 msgstr "Unbekannter Feldname: %.*s"
 
 #: ref-filter.c:539
 #, c-format
 msgid ""
 "not a git repository, but the field '%.*s' requires access to object data"
-msgstr ""
+msgstr "Kein Git-Repository, aber das Feld '%.*s' erfordert Zugriff auf Objektdaten."
 
 #: ref-filter.c:663
 #, c-format
 msgid "format: %%(if) atom used without a %%(then) atom"
 msgstr "format: %%(if) Atom ohne ein %%(then) Atom verwendet"
 
 #: ref-filter.c:726
 #, c-format
@@ -4446,113 +4438,111 @@ msgstr "doppelte ersetzende Referenz: %s"
 
 #: replace-object.c:73
 #, c-format
 msgid "replace depth too high for object %s"
 msgstr "Ersetzungstiefe zu hoch für Objekt %s"
 
 #: rerere.c:217 rerere.c:226 rerere.c:229
 msgid "corrupt MERGE_RR"
-msgstr ""
+msgstr "Fehlerhaftes MERGE_RR"
 
 #: rerere.c:264 rerere.c:269
-#, fuzzy
 msgid "unable to write rerere record"
-msgstr "Konnte Notiz-Objekt nicht schreiben"
+msgstr "Konnte Rerere-Eintrag nicht schreiben."
 
 #: rerere.c:485 rerere.c:692 sequencer.c:3136 sequencer.c:3162
 #, c-format
 msgid "could not write '%s'"
 msgstr "Konnte '%s' nicht schreiben."
 
 #: rerere.c:495
-#, fuzzy, c-format
+#, c-format
 msgid "there were errors while writing '%s' (%s)"
-msgstr "Lesefehler beim Indizieren von '%s'."
+msgstr "Fehler beim Schreiben von '%s' (%s)."
 
 #: rerere.c:498
-#, fuzzy, c-format
+#, c-format
 msgid "failed to flush '%s'"
-msgstr "Konnte '%s' nicht lesen"
+msgstr "Flush bei '%s' fehlgeschlagen."
 
 #: rerere.c:503 rerere.c:1039
-#, fuzzy, c-format
+#, c-format
 msgid "could not parse conflict hunks in '%s'"
-msgstr "Konnte Commit '%s' nicht parsen."
+msgstr "Konnte Konflikt-Blöcke in '%s' nicht parsen."
 
 #: rerere.c:684
-#, fuzzy, c-format
+#, c-format
 msgid "failed utime() on '%s'"
 msgstr "Fehler beim Aufruf von utime() auf '%s'."
 
 #: rerere.c:694
-#, fuzzy, c-format
+#, c-format
 msgid "writing '%s' failed"
-msgstr "Konnte '%s' nicht erstellen"
+msgstr "Schreiben von '%s' fehlgeschlagen."
 
 #: rerere.c:714
 #, c-format
 msgid "Staged '%s' using previous resolution."
-msgstr ""
+msgstr "'%s' mit vorheriger Konfliktauflösung zum Commit vorgemerkt."
 
 #: rerere.c:753
-#, fuzzy, c-format
+#, c-format
 msgid "Recorded resolution for '%s'."
-msgstr "aufgezeichnete Auflösung von Merge-Konflikten wiederverwenden"
+msgstr "Konfliktauflösung für '%s' aufgezeichnet."
 
 #: rerere.c:788
 #, c-format
 msgid "Resolved '%s' using previous resolution."
-msgstr ""
+msgstr "Konflikte in '%s' mit vorheriger Konfliktauflösung beseitigt."
 
 #: rerere.c:803
-#, fuzzy, c-format
+#, c-format
 msgid "cannot unlink stray '%s'"
-msgstr "kann symbolische Verknüpfung '%s' auf '%s' nicht erstellen"
+msgstr "Kann '%s' nicht löschen."
 
 #: rerere.c:807
-#, fuzzy, c-format
+#, c-format
 msgid "Recorded preimage for '%s'"
-msgstr "Konnte Log für '%s' nicht parsen."
+msgstr "Preimage für '%s' aufgezeichnet."
 
 #: rerere.c:881 submodule.c:1763 builtin/submodule--helper.c:1413
 #: builtin/submodule--helper.c:1423
 #, c-format
 msgid "could not create directory '%s'"
 msgstr "Konnte Verzeichnis '%s' nicht erstellen."
 
 #: rerere.c:1057
-#, fuzzy, c-format
+#, c-format
 msgid "failed to update conflicted state in '%s'"
-msgstr "Fehler beim Ausführen von 'git status' auf '%s'"
+msgstr "Fehler beim Aktualisieren des Konflikt-Status in '%s'."
 
 #: rerere.c:1068 rerere.c:1075
-#, fuzzy, c-format
+#, c-format
 msgid "no remembered resolution for '%s'"
-msgstr "Konnte Merge-Ergebnis von '%s' nicht hinzufügen."
+msgstr "Keine aufgezeichnete Konfliktauflösung für '%s'."
 
 #: rerere.c:1077
-#, fuzzy, c-format
+#, c-format
 msgid "cannot unlink '%s'"
-msgstr "kann Verweis '%s' nicht lesen"
+msgstr "Kann '%s' nicht löschen."
 
 #: rerere.c:1087
-#, fuzzy, c-format
+#, c-format
 msgid "Updated preimage for '%s'"
-msgstr "Ersetzende Referenz '%s' gelöscht."
+msgstr "Preimage für '%s' aktualisiert."
 
 #: rerere.c:1096
-#, fuzzy, c-format
+#, c-format
 msgid "Forgot resolution for '%s'\n"
-msgstr "Konnte Log für '%s' nicht parsen."
+msgstr "Aufgezeichnete Konfliktauflösung für '%s' gelöscht.\n"
 
 #: rerere.c:1199
-#, fuzzy
 msgid "unable to open rr-cache directory"
-msgstr "Konnte Cache-Verzeichnis nicht aktualisieren."
+msgstr "Konnte rr-cache Verzeichnis nicht öffnen."
 
 #: revision.c:2324
 msgid "your current branch appears to be broken"
 msgstr "Ihr aktueller Branch scheint fehlerhaft zu sein."
 
 #: revision.c:2327
 #, c-format
 msgid "your current branch '%s' does not have any commits yet"
@@ -4562,19 +4552,19 @@ msgstr "Ihr aktueller Branch '%s' hat noch keine Commits."
 msgid "--first-parent is incompatible with --bisect"
 msgstr "Die Optionen --first-parent und --bisect sind inkompatibel."
 
 #: run-command.c:740
 msgid "open /dev/null failed"
 msgstr "Öffnen von /dev/null fehlgeschlagen"
 
 #: run-command.c:1229
-#, fuzzy, c-format
+#, c-format
 msgid "cannot create async thread: %s"
-msgstr "kann Thread nicht erzeugen: %s"
+msgstr "Kann Thread für async nicht erzeugen: %s"
 
 #: run-command.c:1293
 #, c-format
 msgid ""
 "The '%s' hook was ignored because it's not set as executable.\n"
 "You can disable this warning with `git config advice.ignoredHook false`."
 msgstr ""
 "Der '%s' Hook wurde ignoriert, weil er nicht als ausführbar markiert ist.\n"
@@ -4715,59 +4705,59 @@ msgstr "%s: Konnte neue Index-Datei nicht schreiben"
 msgid "unable to update cache tree"
 msgstr "Konnte Cache-Verzeichnis nicht aktualisieren."
 
 #: sequencer.c:604
 msgid "could not resolve HEAD commit"
 msgstr "Konnte HEAD-Commit nicht auflösen."
 
 #: sequencer.c:684
-#, fuzzy, c-format
+#, c-format
 msgid "no key present in '%.*s'"
-msgstr "Konnte '%.*s' nicht parsen."
+msgstr "Kein Schlüssel in '%.*s' vorhanden."
 
 #: sequencer.c:695
-#, fuzzy, c-format
+#, c-format
 msgid "unable to dequote value of '%s'"
-msgstr "Konnte Remote-Helper für '%s' nicht finden."
+msgstr "Konnte Anführungszeichen von '%s' nicht entfernen."
 
 #: sequencer.c:732 wrapper.c:227 wrapper.c:397 builtin/am.c:719
 #: builtin/am.c:811 builtin/merge.c:1081
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr "Konnte '%s' nicht zum Lesen öffnen."
 
 #: sequencer.c:742
 msgid "'GIT_AUTHOR_NAME' already given"
-msgstr ""
+msgstr "'GIT_AUTHOR_NAME' bereits angegeben."
 
 #: sequencer.c:747
 msgid "'GIT_AUTHOR_EMAIL' already given"
-msgstr ""
+msgstr "'GIT_AUTHOR_EMAIL' bereits angegeben."
 
 #: sequencer.c:752
 msgid "'GIT_AUTHOR_DATE' already given"
-msgstr ""
+msgstr "'GIT_AUTHOR_DATE' bereits angegeben."
 
 #: sequencer.c:756
-#, fuzzy, c-format
+#, c-format
 msgid "unknown variable '%s'"
-msgstr "Unbekanntes Archivformat '%s'"
+msgstr "Unbekannte Variable '%s'"
 
 #: sequencer.c:761
 msgid "missing 'GIT_AUTHOR_NAME'"
-msgstr ""
+msgstr "'GIT_AUTHOR_NAME' fehlt."
 
 #: sequencer.c:763
 msgid "missing 'GIT_AUTHOR_EMAIL'"
-msgstr ""
+msgstr "'GIT_AUTHOR_EMAIL' fehlt."
 
 #: sequencer.c:765
 msgid "missing 'GIT_AUTHOR_DATE'"
-msgstr ""
+msgstr "'GIT_AUTHOR_DATE' fehlt."
 
 #: sequencer.c:825
 #, c-format
 msgid "invalid date format '%s' in '%s'"
 msgstr "Ungültiges Datumsformat '%s' in '%s'"
 
 #: sequencer.c:842
 #, c-format
@@ -5310,38 +5300,38 @@ msgid ""
 "Your changes are safe in the stash.\n"
 "You can run \"git stash pop\" or \"git stash drop\" at any time.\n"
 msgstr ""
 "Anwendung des automatischen Stash resultierte in Konflikten.\n"
 "Ihre Änderungen sind im Stash sicher.\n"
 "Sie können jederzeit \"git stash pop\" oder \"git stash drop\" ausführen.\n"
 
 #: sequencer.c:3427
-#, fuzzy, c-format
+#, c-format
 msgid "could not checkout %s"
-msgstr "kann %s nicht auschecken"
+msgstr "Konnte %s nicht auschecken."
 
 #: sequencer.c:3441
-#, fuzzy, c-format
+#, c-format
 msgid "%s: not a valid OID"
-msgstr "%s ist kein gültiges Objekt"
+msgstr "%s: keine gültige OID"
 
 #: sequencer.c:3446 git-rebase--preserve-merges.sh:724
 msgid "could not detach HEAD"
 msgstr "Konnte HEAD nicht loslösen"
 
 #: sequencer.c:3461
-#, fuzzy, c-format
+#, c-format
 msgid "Stopped at HEAD\n"
-msgstr "Angehalten bei %s... %.*s\n"
+msgstr "Angehalten bei HEAD\n"
 
 #: sequencer.c:3463
-#, fuzzy, c-format
+#, c-format
 msgid "Stopped at %s\n"
-msgstr "Angehalten bei %s... %.*s\n"
+msgstr "Angehalten bei %s\n"
 
 #: sequencer.c:3471
 #, c-format
 msgid ""
 "Could not execute the todo command\n"
 "\n"
 "    %.*s\n"
 "It has been rescheduled; To edit the command before continuing, please\n"
@@ -5495,41 +5485,38 @@ msgid ""
 "continue'.\n"
 "Or you can abort the rebase with 'git rebase --abort'.\n"
 msgstr ""
 "Sie können das mit 'git rebase --edit-todo' beheben. Führen Sie danach\n"
 "'git rebase --continue' aus.\n"
 "Oder Sie können den Rebase mit 'git rebase --abort' abbrechen.\n"
 
 #: sequencer.c:4848 sequencer.c:4886
-#, fuzzy
 msgid "nothing to do"
-msgstr "nichts zu committen\n"
+msgstr "Nichts zu tun."
 
 #: sequencer.c:4852
-#, fuzzy, c-format
+#, c-format
 msgid "Rebase %s onto %s (%d command)"
 msgid_plural "Rebase %s onto %s (%d commands)"
-msgstr[0] "Rebase von $shortrevisions auf $shortonto ($todocount Kommando)"
-msgstr[1] "Rebase von $shortrevisions auf $shortonto ($todocount Kommandos)"
+msgstr[0] "Rebase von %s auf %s (%d Kommando)"
+msgstr[1] "Rebase von %s auf %s (%d Kommandos)"
 
 #: sequencer.c:4864
-#, fuzzy, c-format
+#, c-format
 msgid "could not copy '%s' to '%s'."
 msgstr "Konnte '%s' nicht nach '%s' kopieren."
 
 #: sequencer.c:4868 sequencer.c:4897
-#, fuzzy
 msgid "could not transform the todo list"
-msgstr "Konnte TODO-Liste nicht erzeugen."
+msgstr "Konnte die TODO-Liste nicht umwandeln."
 
 #: sequencer.c:4900
-#, fuzzy
 msgid "could not skip unnecessary pick commands"
-msgstr "nicht erforderliche \"pick\"-Befehle auslassen"
+msgstr "Konnte unnötige \"pick\"-Befehle nicht auslassen."
 
 #: sequencer.c:4983
 msgid "the script was already rearranged."
 msgstr "Das Script wurde bereits umgeordnet."
 
 #: setup.c:123
 #, c-format
 msgid "'%s' is outside repository"
@@ -6091,17 +6078,17 @@ msgstr "Ignoriere verdächtigen Submodulnamen: %s"
 
 #: submodule-config.c:296
 msgid "negative values not allowed for submodule.fetchjobs"
 msgstr "Negative Werte für submodule.fetchjobs nicht erlaubt."
 
 #: submodule-config.c:390
 #, c-format
 msgid "ignoring '%s' which may be interpreted as a command-line option: %s"
-msgstr ""
+msgstr "Ignoriere '%s', was als eine Befehlszeilenoption '%s' interpretiert werden würde."
 
 #: submodule-config.c:479
 #, c-format
 msgid "invalid value for %s"
 msgstr "Ungültiger Wert für %s"
 
 #: submodule-config.c:754
 #, c-format
@@ -6690,16 +6677,19 @@ msgid "Checking out files"
 msgstr "Checke Dateien aus"
 
 #: unpack-trees.c:368
 msgid ""
 "the following paths have collided (e.g. case-sensitive paths\n"
 "on a case-insensitive filesystem) and only one from the same\n"
 "colliding group is in the working tree:\n"
 msgstr ""
+"Die folgenden Pfade haben kollidiert (z.B. case-sensitive Pfade\n"
+"auf einem case-insensitiven Dateisystem) und nur einer von der\n"
+"selben Kollissionsgruppe ist im Arbeitsverzeichnis:\n"
 
 #: urlmatch.c:163
 msgid "invalid URL scheme name or missing '://' suffix"
 msgstr "Ungültiges URL-Schema oder Suffix '://' fehlt"
 
 #: urlmatch.c:187 urlmatch.c:346 urlmatch.c:405
 #, c-format
 msgid "invalid %XX escape sequence"
@@ -7571,17 +7561,17 @@ msgstr ""
 #, c-format
 msgid "To restore the original branch and stop patching, run \"%s --abort\"."
 msgstr ""
 "Um den ursprünglichen Branch wiederherzustellen und die Anwendung der "
 "Patches abzubrechen, führen Sie \"%s --abort\" aus."
 
 #: builtin/am.c:1196
 msgid "Patch sent with format=flowed; space at the end of lines might be lost."
-msgstr ""
+msgstr "Patch mit format=flowed versendet; Leerzeichen am Ende von Zeilen könnte verloren gehen."
 
 #: builtin/am.c:1224
 msgid "Patch is empty."
 msgstr "Patch ist leer."
 
 #: builtin/am.c:1290
 #, c-format
 msgid "invalid ident line: %.*s"
@@ -8584,19 +8574,18 @@ msgstr ""
 msgid ""
 "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
 "filters]"
 msgstr ""
 "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
 "filters]"
 
 #: builtin/cat-file.c:609
-#, fuzzy
 msgid "only one batch option may be specified"
-msgstr "Nur eine Aktion erlaubt."
+msgstr "Nur eine Batch-Option erlaubt."
 
 #: builtin/cat-file.c:627
 msgid "<type> can be one of: blob, tree, commit, tag"
 msgstr "<Art> kann sein: blob, tree, commit, tag"
 
 #: builtin/cat-file.c:628
 msgid "show object type"
 msgstr "Objektart anzeigen"
@@ -10363,19 +10352,18 @@ msgstr "globale Konfigurationsdatei verwenden"
 msgid "use system config file"
 msgstr "systemweite Konfigurationsdatei verwenden"
 
 #: builtin/config.c:127
 msgid "use repository config file"
 msgstr "Konfigurationsdatei des Repositories verwenden"
 
 #: builtin/config.c:128
-#, fuzzy
 msgid "use per-worktree config file"
-msgstr "Konfigurationsdatei des Repositories verwenden"
+msgstr "Konfigurationsdatei pro Arbeitsverzeichnis verwenden"
 
 #: builtin/config.c:129
 msgid "use given config file"
 msgstr "die angegebene Konfigurationsdatei verwenden"
 
 #: builtin/config.c:130
 msgid "blob-id"
 msgstr "Blob-Id"
@@ -10576,16 +10564,19 @@ msgid "$HOME not set"
 msgstr "$HOME nicht gesetzt."
 
 #: builtin/config.c:657
 msgid ""
 "--worktree cannot be used with multiple working trees unless the config\n"
 "extension worktreeConfig is enabled. Please read \"CONFIGURATION FILE\"\n"
 "section in \"git help worktree\" for details"
 msgstr ""
+"--worktree kann nicht mit mehreren Arbeitsverzeichnissen verwendet werden,\n"
+"außer die Konfigurationserweiterung worktreeConfig ist aktiviert. Bitte\n"
+"lesen Sie die Sektion \"CONFIGURATION_FILE\" in \"git help worktree\" für Details"
 
 #: builtin/config.c:687
 msgid "--get-color and variable type are incoherent"
 msgstr "Angabe von --get-color und Variablentyp sind ungültig."
 
 #: builtin/config.c:692
 msgid "only one action at a time"
 msgstr "Nur eine Aktion erlaubt."
@@ -11030,19 +11021,18 @@ msgstr "fordert von allen Remote-Repositories an"
 msgid "append to .git/FETCH_HEAD instead of overwriting"
 msgstr "an .git/FETCH_HEAD anhängen, anstatt zu überschreiben"
 
 #: builtin/fetch.c:119 builtin/pull.c:200
 msgid "path to upload pack on remote end"
 msgstr "Pfad des Programms zum Hochladen von Paketen auf der Gegenseite"
 
 #: builtin/fetch.c:120
-#, fuzzy
 msgid "force overwrite of local reference"
-msgstr "das Überschreiben von lokalen Branches erzwingen"
+msgstr "das Überschreiben einer lokalen Referenz erzwingen"
 
 #: builtin/fetch.c:122
 msgid "fetch from multiple remotes"
 msgstr "von mehreren Remote-Repositories anfordern"
 
 #: builtin/fetch.c:124 builtin/pull.c:204
 msgid "fetch all tags and associated objects"
 msgstr "alle Tags und verbundene Objekte anfordern"
@@ -11171,17 +11161,17 @@ msgstr "[Tag Aktualisierung]"
 
 #: builtin/fetch.c:731 builtin/fetch.c:771 builtin/fetch.c:787
 #: builtin/fetch.c:802
 msgid "unable to update local ref"
 msgstr "kann lokale Referenz nicht aktualisieren"
 
 #: builtin/fetch.c:735
 msgid "would clobber existing tag"
-msgstr ""
+msgstr "würde bestehende Tags verändern"
 
 #: builtin/fetch.c:757
 msgid "[new tag]"
 msgstr "[neues Tag]"
 
 #: builtin/fetch.c:760
 msgid "[new branch]"
 msgstr "[neuer Branch]"
@@ -11655,19 +11645,18 @@ msgstr "binäre Dateien als Text verarbeiten"
 msgid "don't match patterns in binary files"
 msgstr "keine Muster in Binärdateien finden"
 
 #: builtin/grep.c:822
 msgid "process binary files with textconv filters"
 msgstr "binäre Dateien mit \"textconv\"-Filtern verarbeiten"
 
 #: builtin/grep.c:824
-#, fuzzy
 msgid "search in subdirectories (default)"
-msgstr "lose Referenzen entfernen (Standard)"
+msgstr "in Unterverzeichnissen suchen (Standard)"
 
 #: builtin/grep.c:826
 msgid "descend at most <depth> levels"
 msgstr "höchstens <Tiefe> Ebenen durchlaufen"
 
 #: builtin/grep.c:830
 msgid "use extended POSIX regular expressions"
 msgstr "erweiterte reguläre Ausdrücke aus POSIX verwenden"
@@ -11817,19 +11806,18 @@ msgid "--no-index or --untracked cannot be used with revs"
 msgstr "--no-index oder --untracked können nicht mit Commits verwendet werden"
 
 #: builtin/grep.c:1020
 #, c-format
 msgid "unable to resolve revision: %s"
 msgstr "Konnte Commit nicht auflösen: %s"
 
 #: builtin/grep.c:1051
-#, fuzzy
 msgid "invalid option combination, ignoring --threads"
-msgstr "keine Unterstützung von Threads, --threads wird ignoriert"
+msgstr "ungültige Kombination von Optionen, --threads wird ignoriert"
 
 #: builtin/grep.c:1054 builtin/pack-objects.c:3395
 msgid "no threads support, ignoring --threads"
 msgstr "keine Unterstützung von Threads, --threads wird ignoriert"
 
 #: builtin/grep.c:1057 builtin/index-pack.c:1503 builtin/pack-objects.c:2716
 #, c-format
 msgid "invalid number of threads specified (%d)"
@@ -11993,19 +11981,19 @@ msgid "no info viewer handled the request"
 msgstr "kein Informations-Betrachter konnte mit dieser Anfrage umgehen"
 
 #: builtin/help.c:430 builtin/help.c:441 git.c:322
 #, c-format
 msgid "'%s' is aliased to '%s'"
 msgstr "Für '%s' wurde der Alias '%s' angelegt."
 
 #: builtin/help.c:444
-#, fuzzy, c-format
+#, c-format
 msgid "bad alias.%s string: %s"
-msgstr "Ungültiger branch.%s.mergeoptions String: %s"
+msgstr "Ungültiger alias.%s String: %s"
 
 #: builtin/help.c:473 builtin/help.c:503
 #, c-format
 msgid "usage: %s%s"
 msgstr "Verwendung: %s%s"
 
 #: builtin/help.c:487
 msgid "'git help config' for more information"
@@ -12460,17 +12448,17 @@ msgid "join whitespace-continued values"
 msgstr "durch Leerzeichen fortgesetzte Werte verbinden"
 
 #: builtin/interpret-trailers.c:107
 msgid "set parsing options"
 msgstr "Optionen für das Parsen setzen"
 
 #: builtin/interpret-trailers.c:109
 msgid "do not treat --- specially"
-msgstr ""
+msgstr "--- nicht speziell behandeln"
 
 #: builtin/interpret-trailers.c:110
 msgid "trailer"
 msgstr "Anhang"
 
 #: builtin/interpret-trailers.c:111
 msgid "trailer(s) to add"
 msgstr "Anhang/Anhänge hinzufügen"
@@ -12621,19 +12609,18 @@ msgstr "Basis-Commit sollte der Vorgänger der Revisionsliste sein."
 msgid "base commit shouldn't be in revision list"
 msgstr "Basis-Commit sollte nicht in der Revisionsliste enthalten sein."
 
 #: builtin/log.c:1418
 msgid "cannot get patch id"
 msgstr "kann Patch-Id nicht lesen"
 
 #: builtin/log.c:1470
-#, fuzzy
 msgid "failed to infer range-diff ranges"
-msgstr "Fehler beim Generieren des Diffs."
+msgstr "Fehler beim Ableiten des range-diff-Bereichs."
 
 #: builtin/log.c:1515
 msgid "use [PATCH n/m] even with a single patch"
 msgstr "[PATCH n/m] auch mit einzelnem Patch verwenden"
 
 #: builtin/log.c:1518
 msgid "use [PATCH] even with multiple patches"
 msgstr "[PATCH] auch mit mehreren Patches verwenden"
@@ -12781,30 +12768,28 @@ msgstr "eine Signatur aus einer Datei hinzufügen"
 msgid "don't print the patch filenames"
 msgstr "keine Dateinamen der Patches anzeigen"
 
 #: builtin/log.c:1584
 msgid "show progress while generating patches"
 msgstr "Forschrittsanzeige während der Erzeugung der Patches"
 
 #: builtin/log.c:1585
-#, fuzzy
 msgid "rev"
-msgstr "Revert"
+msgstr "Commit"
 
 #: builtin/log.c:1586
 msgid "show changes against <rev> in cover letter or single patch"
-msgstr ""
+msgstr "Änderungen gegenüber <Commit> im Deckblatt oder einzelnem Patch anzeigen"
 
 #: builtin/log.c:1589
 msgid "show changes against <refspec> in cover letter or single patch"
-msgstr ""
+msgstr "Änderungen gegenüber <Refspec> im Deckblatt oder einzelnem Patch anzeigen"
 
 #: builtin/log.c:1591
-#, fuzzy
 msgid "percentage by which creation is weighted"
 msgstr "Prozentsatz mit welchem Erzeugung gewichtet wird"
 
 #: builtin/log.c:1666
 #, c-format
 msgid "invalid ident line: %s"
 msgstr "Ungültige Identifikationszeile: %s"
 
@@ -12834,43 +12819,43 @@ msgstr "Standard-Ausgabe oder Verzeichnis, welches von beidem?"
 
 #: builtin/log.c:1729
 #, c-format
 msgid "Could not create directory '%s'"
 msgstr "Konnte Verzeichnis '%s' nicht erstellen."
 
 #: builtin/log.c:1816
 msgid "--interdiff requires --cover-letter or single patch"
-msgstr ""
+msgstr "--interdiff erfordert --cover-letter oder einzelnen Patch."
 
 #: builtin/log.c:1820
 msgid "Interdiff:"
-msgstr ""
+msgstr "Interdiff:"
 
 #: builtin/log.c:1821
 #, c-format
 msgid "Interdiff against v%d:"
-msgstr ""
+msgstr "Interdiff gegen v%d:"
 
 #: builtin/log.c:1827
 msgid "--creation-factor requires --range-diff"
-msgstr ""
+msgstr "--creation-factor erfordert --range-diff"
 
 #: builtin/log.c:1831
 msgid "--range-diff requires --cover-letter or single patch"
-msgstr ""
+msgstr "--range-diff erfordert --cover-letter oder einzelnen Patch."
 
 #: builtin/log.c:1839
 msgid "Range-diff:"
-msgstr ""
+msgstr "Range-Diff:"
 
 #: builtin/log.c:1840
 #, c-format
 msgid "Range-diff against v%d:"
-msgstr ""
+msgstr "Range-Diff gegen v%d:"
 
 #: builtin/log.c:1851
 #, c-format
 msgid "unable to read signature file '%s'"
 msgstr "Konnte Signatur-Datei '%s' nicht lesen"
 
 #: builtin/log.c:1887
 msgid "Generating patches"
@@ -13585,31 +13570,30 @@ msgid "allow missing objects"
 msgstr "fehlende Objekte erlauben"
 
 #: builtin/mktree.c:156
 msgid "allow creation of more than one tree"
 msgstr "die Erstellung von mehr als einem \"Tree\"-Objekt erlauben"
 
 #: builtin/multi-pack-index.c:8
 msgid "git multi-pack-index [--object-dir=<dir>] (write|verify)"
-msgstr ""
+msgstr "git multi-pack-index [--object-dir=<Verzeichnis>] (write|verify)"
 
 #: builtin/multi-pack-index.c:21
 msgid "object directory containing set of packfile and pack-index pairs"
-msgstr ""
+msgstr "Objekt-Verzeichnis, welches Paare von Packdateien und pack-index enthält"
 
 #: builtin/multi-pack-index.c:39
-#, fuzzy
 msgid "too many arguments"
 msgstr "Zu viele Argumente."
 
 #: builtin/multi-pack-index.c:48
-#, fuzzy, c-format
+#, c-format
 msgid "unrecognized verb: %s"
-msgstr "nicht erkanntes Argument: %s"
+msgstr "Nicht erkanntes Verb: %s"
 
 #: builtin/mv.c:17
 msgid "git mv [<options>] <source>... <destination>"
 msgstr "git mv [<Optionen>] <Quelle>... <Ziel>"
 
 #: builtin/mv.c:82
 #, c-format
 msgid "Directory %s is in index and no submodule?"
@@ -14268,19 +14252,19 @@ msgstr "Konnte Kopfbereich von Objekt '%s' nicht parsen."
 
 #: builtin/pack-objects.c:2083 builtin/pack-objects.c:2099
 #: builtin/pack-objects.c:2109
 #, c-format
 msgid "object %s cannot be read"
 msgstr "Objekt %s kann nicht gelesen werden."
 
 #: builtin/pack-objects.c:2086 builtin/pack-objects.c:2113
-#, fuzzy, c-format
+#, c-format
 msgid "object %s inconsistent object length (%<PRIuMAX> vs %<PRIuMAX>)"
-msgstr "Inkonsistente Objektlänge bei Objekt %s (%lu vs. %lu)"
+msgstr "Inkonsistente Objektlänge bei Objekt %s (%<PRIuMAX> vs %<PRIuMAX>)"
 
 #: builtin/pack-objects.c:2123
 msgid "suboptimal pack - out of memory"
 msgstr "ungünstiges Packet - Speicher voll"
 
 #: builtin/pack-objects.c:2451
 #, c-format
 msgid "Delta compression using up to %d threads"
@@ -14512,19 +14496,18 @@ msgstr "Behandlung für fehlende Objekte"
 
 #: builtin/pack-objects.c:3314
 msgid "do not pack objects in promisor packfiles"
 msgstr ""
 "keine Objekte aus Packdateien von partiell geklonten Remote-Repositories "
 "packen"
 
 #: builtin/pack-objects.c:3316
-#, fuzzy
 msgid "respect islands during delta compression"
-msgstr "Größe des Fensters für die Delta-Kompression"
+msgstr "Delta-Islands bei Delta-Kompression beachten"
 
 #: builtin/pack-objects.c:3340
 #, c-format
 msgid "delta chain depth %d is too deep, forcing %d"
 msgstr "Tiefe für Verkettung von Unterschieden %d ist zu tief, erzwinge %d"
 
 #: builtin/pack-objects.c:3345
 #, c-format
@@ -14735,19 +14718,19 @@ msgid ""
 "Your configuration specifies to merge with the ref '%s'\n"
 "from the remote, but no such ref was fetched."
 msgstr ""
 "Ihre Konfiguration gibt an, den Merge mit Referenz '%s'\n"
 "des Remote-Repositories durchzuführen, aber diese Referenz\n"
 "wurde nicht angefordert."
 
 #: builtin/pull.c:565
-#, fuzzy, c-format
+#, c-format
 msgid "unable to access commit %s"
-msgstr "Konnte Commit '%s' nicht parsen."
+msgstr "Konnte nicht auf Commit '%s' zugreifen."
 
 #: builtin/pull.c:843
 msgid "ignoring --verify-signatures for rebase"
 msgstr "Ignoriere --verify-signatures für Rebase"
 
 #: builtin/pull.c:891
 msgid "--[no-]autostash option is only valid with --rebase."
 msgstr "--[no-]autostash ist nur mit --rebase zulässig."
@@ -15214,63 +15197,59 @@ msgstr "weder den Index, noch das Arbeitsverzeichnis aktualisieren"
 msgid "skip applying sparse checkout filter"
 msgstr "Anwendung des Filters für partielles Auschecken überspringen"
 
 #: builtin/read-tree.c:152
 msgid "debug unpack-trees"
 msgstr "unpack-trees protokollieren"
 
 #: builtin/rebase.c:29
-#, fuzzy
 msgid ""
 "git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] "
 "[<branch>]"
-msgstr ""
-"git archive --remote <Repository> [--exec <Programm>] [<Optionen>] <Commit-"
-"Referenz> [<Pfad>...]"
+msgstr "git rebase [-i] [<Optionen>] [--exec <Programm>] [--onto <neue-Basis>] [<Upstream>] [<Branch>]"
 
 #: builtin/rebase.c:31
 msgid ""
 "git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]"
-msgstr ""
+msgstr "git rebase [-i] [<Optionen>] [--exec <Programm>] [--onto <neue-Basis>] --root [<Branch>]"
 
 #: builtin/rebase.c:33
-#, fuzzy
 msgid "git rebase --continue | --abort | --skip | --edit-todo"
-msgstr "git am [<Optionen>] (--continue | --skip | --abort)"
+msgstr "git rebase --continue | --abort | --skip | --edit-todo"
 
 #: builtin/rebase.c:119
-#, fuzzy, c-format
+#, c-format
 msgid "%s requires an interactive rebase"
-msgstr "interaktiv ausführen"
+msgstr "%s erfordert ein interaktives Rebase"
 
 #: builtin/rebase.c:171
-#, fuzzy, c-format
+#, c-format
 msgid "could not get 'onto': '%s'"
-msgstr "Konnte '%s' nicht zu '%s' setzen."
+msgstr "Konnte 'onto' nicht bestimmen: '%s'"
 
 #: builtin/rebase.c:186
-#, fuzzy, c-format
+#, c-format
 msgid "invalid orig-head: '%s'"
-msgstr "Ungültige Datei: '%s'"
+msgstr "Ungültiges orig-head: '%s'"
 
 #: builtin/rebase.c:214
 #, c-format
 msgid "ignoring invalid allow_rerere_autoupdate: '%s'"
-msgstr ""
+msgstr "Ignoriere ungültiges allow_rerere_autoupdate: '%s'"
 
 #: builtin/rebase.c:259
-#, fuzzy, c-format
+#, c-format
 msgid "Could not read '%s'"
-msgstr "Konnte '%s' nicht lesen"
+msgstr "Konnte '%s' nicht lesen."
 
 #: builtin/rebase.c:277
-#, fuzzy, c-format
+#, c-format
 msgid "Cannot store %s"
-msgstr "kann %s nicht speichern"
+msgstr "Kann %s nicht speichern."
 
 #: builtin/rebase.c:337
 msgid ""
 "Resolve all conflicts manually, mark them as resolved with\n"
 "\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
 "You can instead skip this commit: run \"git rebase --skip\".\n"
 "To abort and get back to the state before \"git rebase\", run \"git rebase --"
 "abort\"."
@@ -15279,191 +15258,174 @@ msgstr ""
 "\"git add/rm <konfliktbehaftete_Dateien>\" und führen Sie dann\n"
 "\"git rebase --continue\" aus.\n"
 "Sie können auch stattdessen diesen Commit auslassen, indem\n"
 "Sie \"git rebase --skip\" ausführen.\n"
 "Um abzubrechen und zurück zum Zustand vor \"git rebase\" zu gelangen,\n"
 "führen Sie \"git rebase --abort\" aus."
 
 #: builtin/rebase.c:561
-#, fuzzy
 msgid "could not determine HEAD revision"
-msgstr "Konnte HEAD nicht loslösen"
+msgstr "Konnte HEAD-Commit nicht bestimmen."
 
 #: builtin/rebase.c:752
-#, fuzzy, c-format
+#, c-format
 msgid ""
 "%s\n"
 "Please specify which branch you want to rebase against.\n"
 "See git-rebase(1) for details.\n"
 "\n"
 "    git rebase '<branch>'\n"
 "\n"
 msgstr ""
-"Bitte geben Sie den Branch an, gegen welchen Sie \"rebase\" ausführen "
-"möchten."
+"%s\n"
+"Bitte geben Sie den Branch an, gegen welchen Sie \"rebase\" ausführen möchten.\n"
+"Siehe git-rebase(1) für Details.\n"
+"\n"
+"    git rebase '<Branch>'\n"
+"\n"
 
 #: builtin/rebase.c:768
-#, fuzzy, c-format
+#, c-format
 msgid ""
 "If you wish to set tracking information for this branch you can do so with:\n"
 "\n"
 "    git branch --set-upstream-to=%s/<branch> %s\n"
 "\n"
 msgstr ""
-"Wenn Sie Tracking-Informationen für diesen Branch setzen möchten, können "
-"Sie\n"
-"dies tun mit:"
+"Wenn Sie Tracking-Informationen für diesen Branch setzen möchten,\n"
+"können Sie dies tun mit:\n"
+"\n"
+"    git branch --set-upstream-to=%s/<Branch> %s\n"
+"\n"
 
 #: builtin/rebase.c:814
-#, fuzzy
 msgid "rebase onto given branch instead of upstream"
-msgstr "Branch %s kann nicht sein eigener Upstream-Branch sein."
+msgstr "Rebase auf angegebenen Branch anstelle des Upstream-Branches ausführen"
 
 #: builtin/rebase.c:816
-#, fuzzy
 msgid "allow pre-rebase hook to run"
-msgstr "Der \"pre-rebase hook\" hat den Rebase zurückgewiesen."
+msgstr "Ausführung des pre-rebase-Hooks erlauben"
 
 #: builtin/rebase.c:818
 msgid "be quiet. implies --no-stat"
-msgstr ""
+msgstr "weniger Ausgaben (impliziert --no-stat)"
 
 #: builtin/rebase.c:821
 msgid "display a diffstat of what changed upstream"
-msgstr ""
+msgstr "Zusammenfassung der Unterschiede gegenüber dem Upstream-Branch anzeigen"
 
 #: builtin/rebase.c:824
-#, fuzzy
 msgid "do not show diffstat of what changed upstream"
-msgstr "keine Zusammenfassung der Unterschiede am Schluss des Merges anzeigen"
+msgstr "Zusammenfassung der Unterschiede gegenüber dem Upstream-Branch verbergen"
 
 #: builtin/rebase.c:827
-#, fuzzy
 msgid "add a Signed-off-by: line to each commit"
-msgstr "der Commit-Beschreibung eine Signed-off-by Zeile hinzufügen"
+msgstr "eine \"Signed-off-by:\"-Zeile zu jedem Commit hinzufügen"
 
 #: builtin/rebase.c:829 builtin/rebase.c:833 builtin/rebase.c:835
 msgid "passed to 'git am'"
-msgstr ""
+msgstr "an 'git am' übergeben"
 
 #: builtin/rebase.c:837 builtin/rebase.c:839
-#, fuzzy
 msgid "passed to 'git apply'"
-msgstr "an git-apply übergeben"
+msgstr "an 'git-apply' übergeben"
 
 #: builtin/rebase.c:841 builtin/rebase.c:844
 msgid "cherry-pick all commits, even if unchanged"
-msgstr ""
+msgstr "Cherry-Pick auf alle Commits ausführen, auch wenn diese unverändert sind"
 
 #: builtin/rebase.c:846
-#, fuzzy
 msgid "continue"
-msgstr "Rebase fortsetzen"
+msgstr "fortsetzen"
 
 #: builtin/rebase.c:849
-#, fuzzy
 msgid "skip current patch and continue"
-msgstr "den aktuellen Patch auslassen"
+msgstr "den aktuellen Patch auslassen und fortfahren"
 
 #: builtin/rebase.c:851
-#, fuzzy
 msgid "abort and check out the original branch"
-msgstr ""
-"  (benutzen Sie \"git rebase --abort\", um den ursprünglichen Branch "
-"auszuchecken)"
+msgstr "abbrechen und den ursprünglichen Branch auschecken"
 
 #: builtin/rebase.c:854
-#, fuzzy
 msgid "abort but keep HEAD where it is"
-msgstr "Patch-Operation abbrechen, aber HEAD an aktueller Stelle belassen"
+msgstr "abbrechen, aber HEAD an aktueller Stelle belassen"
 
 #: builtin/rebase.c:855
-#, fuzzy
 msgid "edit the todo list during an interactive rebase"
-msgstr ""
-"Die --edit-todo Aktion kann nur während eines interaktiven Rebase verwendet "
-"werden."
+msgstr "TODO-Liste während eines interaktiven Rebase bearbeiten"
 
 #: builtin/rebase.c:858
-#, fuzzy
 msgid "show the patch file being applied or merged"
-msgstr "den Patch, der gerade angewendet wird, anzeigen"
+msgstr "den Patch, der gerade angewendet oder zusammengeführt wird, anzeigen"
 
 #: builtin/rebase.c:861
-#, fuzzy
 msgid "use merging strategies to rebase"
-msgstr "zu verwendende Merge-Strategie"
+msgstr "Merge-Strategien beim Rebase verwenden"
 
 #: builtin/rebase.c:865
 msgid "let the user edit the list of commits to rebase"
-msgstr ""
+msgstr "den Benutzer die Liste der Commits für den Rebase bearbeiten lassen"
 
 #: builtin/rebase.c:869
 msgid "try to recreate merges instead of ignoring them"
-msgstr ""
+msgstr "versuchen, Merges wiederherzustellen anstatt sie zu ignorieren"
 
 #: builtin/rebase.c:873
 msgid "allow rerere to update index  with resolved conflict"
-msgstr ""
+msgstr "Rerere erlauben, den Index mit aufgelöstem Konflikt zu aktualisieren"
 
 #: builtin/rebase.c:876
-#, fuzzy
 msgid "preserve empty commits during rebase"
-msgstr "ursprüngliche, leere Commits erhalten"
+msgstr "leere Commits während des Rebase erhalten"
 
 #: builtin/rebase.c:878
 msgid "move commits that begin with squash!/fixup! under -i"
-msgstr ""
+msgstr "bei -i Commits verschieben, die mit squash!/fixup! beginnen"
 
 #: builtin/rebase.c:884
-#, fuzzy
 msgid "automatically stash/stash pop before and after"
-msgstr "automatischer Stash/Stash-Pop vor und nach eines Rebase"
+msgstr "automatischer Stash/Stash-Pop davor und danach"
 
 #: builtin/rebase.c:886
 msgid "add exec lines after each commit of the editable list"
-msgstr ""
+msgstr "exec-Zeilen nach jedem Commit der editierbaren Liste hinzufügen"
 
 #: builtin/rebase.c:890
-#, fuzzy
 msgid "allow rebasing commits with empty messages"
-msgstr "Commits mit leerer Beschreibung erlauben"
+msgstr "Rebase von Commits mit leerer Beschreibung erlauben"
 
 #: builtin/rebase.c:893
 msgid "try to rebase merges instead of skipping them"
-msgstr ""
+msgstr "versuchen, Rebase mit Merges auszuführen, anstatt diese zu überspringen"
 
 #: builtin/rebase.c:896
-#, fuzzy
 msgid "use 'merge-base --fork-point' to refine upstream"
-msgstr "git merge-base --fork-point <Referenz> [<Commit>]"
+msgstr "'git merge-base --fork-point' benutzen, um Upstream-Branch zu bestimmen"
 
 #: builtin/rebase.c:898
-#, fuzzy
 msgid "use the given merge strategy"
-msgstr "Option für Merge-Strategie"
+msgstr "angegebene Merge-Strategie verwenden"
 
 #: builtin/rebase.c:900 builtin/revert.c:111
 msgid "option"
 msgstr "Option"
 
 #: builtin/rebase.c:901
 msgid "pass the argument through to the merge strategy"
-msgstr ""
+msgstr "Argument zur Merge-Strategie durchreichen"
 
 #: builtin/rebase.c:904
-#, fuzzy
 msgid "rebase all reachable commits up to the root(s)"
-msgstr "alle nicht erreichbaren Objekte von der Objektdatenbank entfernen"
+msgstr "Rebase auf alle erreichbaren Commits bis zum Root-Commit ausführen"
 
 #: builtin/rebase.c:920
-#, fuzzy, c-format
+#, c-format
 msgid "could not exec %s"
-msgstr "konnte %s nicht parsen"
+msgstr "Konnte 'exec %s' nicht ausführen."
 
 #: builtin/rebase.c:938 git-legacy-rebase.sh:213
 msgid "It looks like 'git am' is in progress. Cannot rebase."
 msgstr "'git-am' scheint im Gange zu sein. Kann Rebase nicht durchführen."
 
 #: builtin/rebase.c:979 git-legacy-rebase.sh:387
 msgid "No rebase in progress?"
 msgstr "Kein Rebase im Gange?"
@@ -15482,257 +15444,239 @@ msgstr "Kann HEAD nicht lesen"
 msgid ""
 "You must edit all merge conflicts and then\n"
 "mark them as resolved using git add"
 msgstr ""
 "Sie müssen alle Merge-Konflikte editieren und diese dann\n"
 "mittels \"git add\" als aufgelöst markieren"
 
 #: builtin/rebase.c:1026
-#, fuzzy
 msgid "could not discard worktree changes"
-msgstr "Kann Änderungen im Arbeitsverzeichnis nicht löschen"
+msgstr "Konnte Änderungen im Arbeitsverzeichnis nicht verwerfen."
 
 #: builtin/rebase.c:1044
-#, fuzzy, c-format
+#, c-format
 msgid "could not move back to %s"
-msgstr "Konnte nicht zu $head_name zurückgehen"
+msgstr "Konnte nicht zu %s zurückgehen."
 
 #: builtin/rebase.c:1055 builtin/rm.c:368
 #, c-format
 msgid "could not remove '%s'"
 msgstr "Konnte '%s' nicht löschen"
 
 #: builtin/rebase.c:1081
-#, fuzzy, c-format
+#, c-format
 msgid ""
 "It seems that there is already a %s directory, and\n"
 "I wonder if you are in the middle of another rebase.  If that is the\n"
 "case, please try\n"
 "\t%s\n"
 "If that is not the case, please\n"
 "\t%s\n"
 "and run me again.  I am stopping in case you still have something\n"
 "valuable there.\n"
 msgstr ""
-"Es sieht so aus, als ob es das Verzeichnis $state_dir_base bereits gibt\n"
+"Es sieht so aus, als ob es das Verzeichnis %s bereits gibt\n"
 "und es könnte ein anderer Rebase im Gange sein. Wenn das der Fall ist,\n"
 "probieren Sie bitte\n"
-"\t$cmd_live_rebase\n"
+"\t%s\n"
 "Wenn das nicht der Fall ist, probieren Sie bitte\n"
-"\t$cmd_clear_stale_rebase\n"
+"\t%s\n"
 "und führen Sie diesen Befehl nochmal aus. Es wird angehalten, falls noch\n"
-"etwas Schützenswertes vorhanden ist."
+"etwas Schützenswertes vorhanden ist.\n"
 
 #: builtin/rebase.c:1102
-#, fuzzy
 msgid "switch `C' expects a numerical value"
-msgstr "Schalter '%c' erwartet einen numerischen Wert"
+msgstr "Schalter `C' erwartet einen numerischen Wert."
 
 #: builtin/rebase.c:1139
-#, fuzzy, c-format
+#, c-format
 msgid "Unknown mode: %s"
-msgstr "Unbekannter --patch Modus: %s"
+msgstr "Unbekannter Modus: %s"
 
 #: builtin/rebase.c:1161
 msgid "--strategy requires --merge or --interactive"
-msgstr ""
+msgstr "--strategy erfordert --merge oder --interactive"
 
 #: builtin/rebase.c:1204
 #, c-format
 msgid ""
 "error: cannot combine interactive options (--interactive, --exec, --rebase-"
 "merges, --preserve-merges, --keep-empty, --root + --onto) with am options "
 "(%s)"
-msgstr ""
+msgstr "Fehler: 'interactive'-Optionen (--interactive, --exec, --rebase-merges, --preserve-merges, --keep-empty, --root + --onto ) können nicht mit 'am'-Optionen (%s) kombiniert werden."
 
 #: builtin/rebase.c:1209
-#, fuzzy, c-format
+#, c-format
 msgid ""
 "error: cannot combine merge options (--merge, --strategy, --strategy-option) "
 "with am options (%s)"
-msgstr ""
-"Fehler: '--rebase-merges' und '--strategy-option' können nicht kombiniert "
-"werden."
+msgstr "Fehler: 'merge'-Optionen (--merge, --strategy, --strategy-option) können nicht mit 'am'-Optionen (%s) kombiniert werden."
 
 #: builtin/rebase.c:1229 git-legacy-rebase.sh:528
-#, fuzzy
 msgid "error: cannot combine '--preserve-merges' with '--rebase-merges'"
 msgstr ""
 "Fehler: '--preserve-merges' und '--rebase-merges' können nicht kombiniert "
 "werden."
 
 #: builtin/rebase.c:1234 git-legacy-rebase.sh:534
-#, fuzzy
 msgid "error: cannot combine '--rebase-merges' with '--strategy-option'"
 msgstr ""
 "Fehler: '--rebase-merges' und '--strategy-option' können nicht kombiniert "
 "werden."
 
 #: builtin/rebase.c:1237 git-legacy-rebase.sh:536
-#, fuzzy
 msgid "error: cannot combine '--rebase-merges' with '--strategy'"
 msgstr ""
 "Fehler: '--rebase-merges' und '--strategy' können nicht kombiniert werden."
 
 #: builtin/rebase.c:1261
-#, fuzzy, c-format
+#, c-format
 msgid "invalid upstream '%s'"
-msgstr "Ungültiger Pfad '%s'"
+msgstr "Ungültiger Upstream '%s'"
 
 #: builtin/rebase.c:1267
-#, fuzzy
 msgid "Could not create new root commit"
-msgstr "Konnte neu erstellten Commit nicht analysieren."
+msgstr "Konnte neuen Root-Commit nicht erstellen."
 
 #: builtin/rebase.c:1285
-#, fuzzy, c-format
+#, c-format
 msgid "'%s': need exactly one merge base"
-msgstr "Brauche genau einen Commit-Bereich."
+msgstr "'%s': brauche genau eine Merge-Basis"
 
 #: builtin/rebase.c:1292
-#, fuzzy, c-format
+#, c-format
 msgid "Does not point to a valid commit '%s'"
-msgstr "$onto_name zeigt auf keinen gültigen Commit"
+msgstr "'%s' zeigt auf keinen gültigen Commit."
 
 #: builtin/rebase.c:1317
-#, fuzzy, c-format
+#, c-format
 msgid "fatal: no such branch/commit '%s'"
-msgstr "fatal: Branch/Commit '$branch_name' nicht gefunden"
+msgstr "fatal: Branch/Commit '%s' nicht gefunden"
 
 #: builtin/rebase.c:1325 builtin/submodule--helper.c:37
 #: builtin/submodule--helper.c:1930
 #, c-format
 msgid "No such ref: %s"
 msgstr "Referenz nicht gefunden: %s"
 
 #: builtin/rebase.c:1337
-#, fuzzy
 msgid "Could not resolve HEAD to a revision"
-msgstr "Konnte HEAD-Commit nicht auflösen."
+msgstr "Konnte HEAD zu keinem Commit auflösen."
 
 #: builtin/rebase.c:1377 git-legacy-rebase.sh:657
 msgid "Cannot autostash"
 msgstr "Kann automatischen Stash nicht erzeugen."
 
 #: builtin/rebase.c:1380
-#, fuzzy, c-format
+#, c-format
 msgid "Unexpected stash response: '%s'"
-msgstr "Unerwartetes wanted-ref: '%s'"
+msgstr "Unerwartete 'stash'-Antwort: '%s'"
 
 #: builtin/rebase.c:1386
-#, fuzzy, c-format
+#, c-format
 msgid "Could not create directory for '%s'"
-msgstr "Konnte Verzeichnis '%s' nicht erstellen."
+msgstr "Konnte Verzeichnis für '%s' nicht erstellen."
 
 #: builtin/rebase.c:1389
-#, fuzzy, c-format
+#, c-format
 msgid "Created autostash: %s\n"
-msgstr "Automatischen Stash erzeugt: $stash_abbrev"
+msgstr "Automatischen Stash erzeugt: %s\n"
 
 #: builtin/rebase.c:1392
-#, fuzzy
 msgid "could not reset --hard"
-msgstr "Konnte orig-head nicht lesen."
+msgstr "Konnte 'reset --hard' nicht ausführen."
 
 #: builtin/rebase.c:1393 builtin/reset.c:113
 #, c-format
 msgid "HEAD is now at %s"
 msgstr "HEAD ist jetzt bei %s"
 
 #: builtin/rebase.c:1409 git-legacy-rebase.sh:666
 msgid "Please commit or stash them."
 msgstr "Bitte committen Sie die Änderungen oder benutzen Sie \"stash\"."
 
 #: builtin/rebase.c:1436
-#, fuzzy, c-format
+#, c-format
 msgid "could not parse '%s'"
-msgstr "konnte %s nicht parsen"
+msgstr "Konnte '%s' nicht parsen."
 
 #: builtin/rebase.c:1447
-#, fuzzy, c-format
+#, c-format
 msgid "could not switch to %s"
-msgstr "Konnte nicht nach '%s' schreiben."
+msgstr "Konnte nicht zu %s wechseln."
 
 #: builtin/rebase.c:1458 git-legacy-rebase.sh:689
 #, sh-format
 msgid "HEAD is up to date."
 msgstr "HEAD ist aktuell."
 
 #: builtin/rebase.c:1460
-#, fuzzy, c-format
+#, c-format
 msgid "Current branch %s is up to date.\n"
-msgstr "Aktueller Branch $branch_name ist auf dem neuesten Stand."
+msgstr "Aktueller Branch %s ist auf dem neuesten Stand.\n"
 
 #: builtin/rebase.c:1468 git-legacy-rebase.sh:699
 #, sh-format
 msgid "HEAD is up to date, rebase forced."
 msgstr "HEAD ist aktuell, Rebase erzwungen."
 
 #: builtin/rebase.c:1470
-#, fuzzy, c-format
+#, c-format
 msgid "Current branch %s is up to date, rebase forced.\n"
-msgstr ""
-"Aktueller Branch $branch_name ist auf dem neuesten Stand, Rebase erzwungen."
+msgstr "Aktueller Branch %s ist auf dem neuesten Stand, Rebase erzwungen.\n"
 
 #: builtin/rebase.c:1478 git-legacy-rebase.sh:208
 msgid "The pre-rebase hook refused to rebase."
 msgstr "Der \"pre-rebase hook\" hat den Rebase zurückgewiesen."
 
 #: builtin/rebase.c:1484
-#, fuzzy, c-format
+#, c-format
 msgid "Changes from %s to %s:\n"
-msgstr "Änderungen von $mb zu $onto:"
+msgstr "Änderungen von %s zu %s:\n"
 
 #: builtin/rebase.c:1507
-#, fuzzy, c-format
+#, c-format
 msgid "First, rewinding head to replay your work on top of it...\n"
-msgstr ""
-"Zunächst wird der Branch zurückgespult, um Ihre Änderungen\n"
-"darauf neu anzuwenden ..."
+msgstr "Zunächst wird der Branch zurückgespult, um Ihre Änderungen darauf neu anzuwenden...\n"
 
 #: builtin/rebase.c:1513
-#, fuzzy
 msgid "Could not detach HEAD"
-msgstr "Konnte HEAD nicht loslösen"
+msgstr "Konnte HEAD nicht loslösen."
 
 #: builtin/rebase.c:1522
-#, fuzzy, c-format
+#, c-format
 msgid "Fast-forwarded %s to %s. \n"
-msgstr "Spule vor zu $sha1"
+msgstr "%s zu %s vorgespult.\n"
 
 #: builtin/rebase--interactive.c:24
-#, fuzzy
 msgid "no HEAD?"
 msgstr "Kein HEAD?"
 
 #: builtin/rebase--interactive.c:51
-#, fuzzy, c-format
+#, c-format
 msgid "could not create temporary %s"
-msgstr "konnte temporäre Datei nicht erstellen"
+msgstr "Konnte temporäres Verzeichnis '%s' nicht erstellen."
 
 #: builtin/rebase--interactive.c:57
-#, fuzzy
 msgid "could not mark as interactive"
-msgstr "Konnte nicht als interaktiven Rebase markieren."
+msgstr "Markierung auf interaktiven Rebase fehlgeschlagen."
 
 #: builtin/rebase--interactive.c:101
-#, fuzzy, c-format
+#, c-format
 msgid "could not open %s"
-msgstr "Konnte '%s' nicht öffnen"
+msgstr "Konnte '%s' nicht öffnen."
 
 #: builtin/rebase--interactive.c:114
-#, fuzzy
 msgid "could not generate todo list"
 msgstr "Konnte TODO-Liste nicht erzeugen."
 
 #: builtin/rebase--interactive.c:129
-#, fuzzy
 msgid "git rebase--interactive [<options>]"
-msgstr "git rebase--helper [<Optionen>]"
+msgstr "git rebase--interactive [<Optionen>]"
 
 #: builtin/rebase--interactive.c:148
 msgid "keep empty commits"
 msgstr "leere Commits behalten"
 
 #: builtin/rebase--interactive.c:150 builtin/revert.c:124
 msgid "allow commits with empty messages"
 msgstr "Commits mit leerer Beschreibung erlauben"
@@ -15742,41 +15686,37 @@ msgid "rebase merge commits"
 msgstr "Rebase auf Merge-Commits ausführen"
 
 #: builtin/rebase--interactive.c:153
 msgid "keep original branch points of cousins"
 msgstr "originale Branch-Punkte der Cousins behalten"
 
 #: builtin/rebase--interactive.c:155
 msgid "move commits that begin with squash!/fixup!"
-msgstr ""
+msgstr "Commits verschieben, die mit squash!/fixup! beginnen"
 
 #: builtin/rebase--interactive.c:156
-#, fuzzy
 msgid "sign commits"
-msgstr "Commits mit GPG signieren"
+msgstr "Commits signieren"
 
 #: builtin/rebase--interactive.c:158
 msgid "continue rebase"
 msgstr "Rebase fortsetzen"
 
 #: builtin/rebase--interactive.c:160
-#, fuzzy
 msgid "skip commit"
-msgstr "Commit"
+msgstr "Commit auslassen"
 
 #: builtin/rebase--interactive.c:161
-#, fuzzy
 msgid "edit the todo list"
-msgstr "die TODO-Liste prüfen"
+msgstr "die TODO-Liste bearbeiten"
 
 #: builtin/rebase--interactive.c:163
-#, fuzzy
 msgid "show the current patch"
-msgstr "den aktuellen Patch auslassen"
+msgstr "den aktuellen Patch anzeigen"
 
 #: builtin/rebase--interactive.c:166
 msgid "shorten commit ids in the todo list"
 msgstr "Commit-IDs in der TODO-Liste verkürzen"
 
 #: builtin/rebase--interactive.c:168
 msgid "expand commit ids in the todo list"
 msgstr "Commit-IDs in der TODO-Liste erweitern"
@@ -15790,104 +15730,89 @@ msgid "rearrange fixup/squash lines"
 msgstr "fixup/squash-Zeilen umordnen"
 
 #: builtin/rebase--interactive.c:174
 msgid "insert exec commands in todo list"
 msgstr "\"exec\"-Befehle in TODO-Liste einfügen"
 
 #: builtin/rebase--interactive.c:175
 msgid "onto"
-msgstr ""
+msgstr "auf"
 
 #: builtin/rebase--interactive.c:177
-#, fuzzy
 msgid "restrict-revision"
-msgstr "Commit"
+msgstr "Begrenzungscommit"
 
 #: builtin/rebase--interactive.c:177
-#, fuzzy
 msgid "restrict revision"
-msgstr "Commit"
+msgstr "Begrenzungscommit"
 
 #: builtin/rebase--interactive.c:178
-#, fuzzy
 msgid "squash-onto"
-msgstr "squash-onto schreiben"
+msgstr "squash-onto"
 
 #: builtin/rebase--interactive.c:179
-#, fuzzy
 msgid "squash onto"
-msgstr "squash-onto schreiben"
+msgstr "squash onto"
 
 #: builtin/rebase--interactive.c:181
-#, fuzzy
 msgid "the upstream commit"
-msgstr "Informationen zum Upstream-Branch entfernen"
+msgstr "der Upstream-Commit"
 
 #: builtin/rebase--interactive.c:182
-#, fuzzy
 msgid "head-name"
-msgstr "umbenennen"
+msgstr "head-Name"
 
 #: builtin/rebase--interactive.c:182
-#, fuzzy
 msgid "head name"
-msgstr "voraus "
+msgstr "head-Name"
 
 #: builtin/rebase--interactive.c:187
-#, fuzzy
 msgid "rebase strategy"
-msgstr "Merge-Strategie"
+msgstr "Rebase-Strategie"
 
 #: builtin/rebase--interactive.c:188
-#, fuzzy
 msgid "strategy-opts"
-msgstr "Strategie"
+msgstr "Strategie-Optionen"
 
 #: builtin/rebase--interactive.c:189
-#, fuzzy
 msgid "strategy options"
-msgstr "decorate-Optionen"
+msgstr "Strategie-Optionen"
 
 #: builtin/rebase--interactive.c:190
 msgid "switch-to"
-msgstr ""
+msgstr "wechseln zu"
 
 #: builtin/rebase--interactive.c:191
-#, fuzzy
 msgid "the branch or commit to checkout"
-msgstr "einzelnen Commit zu einem ausgecheckten CSV-Repository exportieren"
+msgstr "der Branch oder Commit zum Auschecken"
 
 #: builtin/rebase--interactive.c:192
-#, fuzzy
 msgid "onto-name"
-msgstr "Name"
+msgstr "onto-Name"
 
 #: builtin/rebase--interactive.c:192
-#, fuzzy
 msgid "onto name"
-msgstr "Name des Remote-Repositories"
+msgstr "onto-Name"
 
 #: builtin/rebase--interactive.c:193
-#, fuzzy
 msgid "cmd"
-msgstr "Programm"
+msgstr "Befehl"
 
 #: builtin/rebase--interactive.c:193
-#, fuzzy
 msgid "the command to run"
-msgstr "Keine Befehle ausgeführt."
+msgstr "auszuführender Befehl"
 
 #: builtin/rebase--interactive.c:220
 msgid "--[no-]rebase-cousins has no effect without --rebase-merges"
 msgstr "--[no-]rebase-cousins hat ohne --rebase-merges keine Auswirkung"
 
 #: builtin/rebase--interactive.c:226
 msgid "a base commit must be provided with --upstream or --onto"
-msgstr ""
+msgstr "Ein Basis-Commit muss mit --upstream oder --onto angegeben werden."
 
 #: builtin/receive-pack.c:33
 msgid "git receive-pack <git-dir>"
 msgstr "git receive-pack <Git-Verzeichnis>"
 
 #: builtin/receive-pack.c:830
 msgid ""
 "By default, updating the current branch in a non-bare repository\n"
@@ -16116,19 +16041,19 @@ msgstr "Konnte Fetch-Map für Refspec %s nicht bekommen"
 msgid "(matching)"
 msgstr "(übereinstimmend)"
 
 #: builtin/remote.c:455
 msgid "(delete)"
 msgstr "(lösche)"
 
 #: builtin/remote.c:629 builtin/remote.c:765 builtin/remote.c:864
-#, fuzzy, c-format
+#, c-format
 msgid "No such remote: '%s'"
-msgstr "Kein solches Remote-Repository '%s'"
+msgstr "Kein solches Remote-Repository: '%s'"
 
 #: builtin/remote.c:646
 #, c-format
 msgid "Could not rename config section '%s' to '%s'"
 msgstr "Konnte Sektion '%s' in Konfiguration nicht nach '%s' umbenennen"
 
 #: builtin/remote.c:666
 #, c-format
@@ -16514,19 +16439,18 @@ msgstr "git-update-server-info nicht ausführen"
 msgid "pass --local to git-pack-objects"
 msgstr "--local an git-pack-objects übergeben"
 
 #: builtin/repack.c:310
 msgid "write bitmap index"
 msgstr "Bitmap-Index schreiben"
 
 #: builtin/repack.c:312
-#, fuzzy
 msgid "pass --delta-islands to git-pack-objects"
-msgstr "--local an git-pack-objects übergeben"
+msgstr "--delta-islands an git-pack-objects übergeben"
 
 #: builtin/repack.c:313
 msgid "approxidate"
 msgstr "Datumsangabe"
 
 #: builtin/repack.c:314
 msgid "with -A, do not loosen objects older than this"
 msgstr "mit -A, keine Objekte älter als dieses Datum löschen"
@@ -16837,22 +16761,22 @@ msgid "git rerere [clear | forget <path>... | status | remaining | diff | gc]"
 msgstr "git rerere [clean | forget <Pfad>... | status | remaining | diff | gc]"
 
 #: builtin/rerere.c:60
 msgid "register clean resolutions in index"
 msgstr "saubere Auflösungen im Index registrieren"
 
 #: builtin/rerere.c:79
 msgid "'git rerere forget' without paths is deprecated"
-msgstr ""
+msgstr "'git rerere forget' ohne Pfade ist veraltet."
 
 #: builtin/rerere.c:111
-#, fuzzy, c-format
+#, c-format
 msgid "unable to generate diff for '%s'"
-msgstr "Fehler beim Generieren des Diffs."
+msgstr "Konnte kein Diff für '%s' generieren."
 
 #: builtin/reset.c:31
 msgid ""
 "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"
 msgstr ""
 "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<Commit>]"
 
 #: builtin/reset.c:32
@@ -16966,16 +16890,21 @@ msgstr "Nicht zum Commit vorgemerkte Änderungen nach Zurücksetzung:"
 #: builtin/reset.c:390
 #, c-format
 msgid ""
 "\n"
 "It took %.2f seconds to enumerate unstaged changes after reset.  You can\n"
 "use '--quiet' to avoid this.  Set the config setting reset.quiet to true\n"
 "to make this the default.\n"
 msgstr ""
+"\n"
+"Es dauerte %.2f Sekunden, um über die nach einem Reset nicht zum Commit\n"
+"vorgemerkten Änderungen zu zählen. Sie können '--quiet' benutzen, um\n"
+"das zu verhindern. Setzen Sie die Konfigurationseinstellung reset.quiet\n"
+"auf \"true\", um das zum Standard zu machen.\n"
 
 #: builtin/reset.c:400
 #, c-format
 msgid "Could not reset index file to revision '%s'."
 msgstr "Konnte Index-Datei nicht zu Commit '%s' setzen."
 
 #: builtin/reset.c:404
 msgid "Could not write new index file."
@@ -17541,24 +17470,23 @@ msgstr ""
 msgid "Recurse into nested submodules"
 msgstr "Rekursion in verschachtelte Submodule durchführen"
 
 #: builtin/submodule--helper.c:568
 msgid "git submodule--helper foreach [--quiet] [--recursive] <command>"
 msgstr "git submodule--helper foreach [--quiet] [--recursive] <Befehl>"
 
 #: builtin/submodule--helper.c:595
-#, fuzzy, c-format
+#, c-format
 msgid ""
 "could not look up configuration '%s'. Assuming this repository is its own "
 "authoritative upstream."
 msgstr ""
-"Konnte Konfiguration '%s' nicht nachschlagen. Nehme an, dass dieses "
-"Repository\n"
-"sein eigenes verbindliches Upstream-Repository ist."
+"Konnte Konfiguration '%s' nicht nachschlagen. Nehme an, dass dieses\n"
+"Repository sein eigenes verbindliches Upstream-Repository ist."
 
 #: builtin/submodule--helper.c:663
 #, c-format
 msgid "Failed to register url for submodule path '%s'"
 msgstr ""
 "Fehler beim Eintragen der URL für Submodul-Pfad '%s' in die Konfiguration."
 
 #: builtin/submodule--helper.c:667
@@ -17763,28 +17691,24 @@ msgid "clone of '%s' into submodule path '%s' failed"
 msgstr "Klonen von '%s' in Submodul-Pfad '%s' fehlgeschlagen"
 
 #: builtin/submodule--helper.c:1433
 #, c-format
 msgid "could not get submodule directory for '%s'"
 msgstr "Konnte Submodul-Verzeichnis '%s' nicht finden."
 
 #: builtin/submodule--helper.c:1469
-#, fuzzy, c-format
+#, c-format
 msgid "Invalid update mode '%s' for submodule path '%s'"
-msgstr ""
-"Fehler bei Änderung des Aktualisierungsmodus für Submodul-Pfad '%s' in der\n"
-"Konfiguration."
+msgstr "Ungültiger Aktualisierungsmodus '%s' für Submodul-Pfad '%s'."
 
 #: builtin/submodule--helper.c:1473
-#, fuzzy, c-format
+#, c-format
 msgid "Invalid update mode '%s' configured for submodule path '%s'"
-msgstr ""
-"Fehler bei Änderung des Aktualisierungsmodus für Submodul-Pfad '%s' in der\n"
-"Konfiguration."
+msgstr "Ungültiger Aktualisierungsmodus '%s' für Submodul-Pfad '%s' konfiguriert."
 
 #: builtin/submodule--helper.c:1566
 #, c-format
 msgid "Submodule path '%s' not initialized"
 msgstr "Submodul-Pfad '%s' nicht initialisiert"
 
 #: builtin/submodule--helper.c:1570
 msgid "Maybe you want to use 'update --init'?"
@@ -17857,48 +17781,44 @@ msgstr "Fehlerhafter Wert für --update Parameter"
 msgid ""
 "Submodule (%s) branch configured to inherit branch from superproject, but "
 "the superproject is not on any branch"
 msgstr ""
 "Branch von Submodul (%s) ist konfiguriert, den Branch des Hauptprojektes\n"
 "zu erben, aber das Hauptprojekt befindet sich auf keinem Branch."
 
 #: builtin/submodule--helper.c:2057
-#, fuzzy, c-format
+#, c-format
 msgid "could not get a repository handle for submodule '%s'"
-msgstr "konnte Name für Submodul '%s' nicht nachschlagen"
+msgstr "Konnte kein Repository-Handle für Submodul '%s' erhalten."
 
 #: builtin/submodule--helper.c:2090
 msgid "recurse into submodules"
 msgstr "Rekursion in Submodule durchführen"
 
 #: builtin/submodule--helper.c:2096
 msgid "git submodule--helper embed-git-dir [<path>...]"
 msgstr "git submodule--helper embed-git-dir [<Pfad>...]"
 
 #: builtin/submodule--helper.c:2152
 msgid "check if it is safe to write to the .gitmodules file"
-msgstr ""
+msgstr "prüfen, ob es sicher ist, in die Datei .gitmodules zu schreiben"
 
 #: builtin/submodule--helper.c:2157
-#, fuzzy
 msgid "git submodule--helper config name [value]"
-msgstr "git submodule--helper name <Pfad>"
+msgstr "git submodule--helper config name [Wert]"
 
 #: builtin/submodule--helper.c:2158
-#, fuzzy
 msgid "git submodule--helper config --check-writeable"
-msgstr "git submodule--helper init [<Pfad>]"
+msgstr "git submodule--helper config --check-writeable"
 
 #: builtin/submodule--helper.c:2175 git-submodule.sh:169
-#, fuzzy, sh-format
+#, sh-format
 msgid "please make sure that the .gitmodules file is in the working tree"
-msgstr ""
-"Bitte merken Sie Ihre Änderungen in .gitmodules zum Commit vor oder\n"
-"benutzen Sie \"stash\", um fortzufahren."
+msgstr "Bitte stellen Sie sicher, dass sich die Datei .gitmodules im Arbeitsverzeichnis befindet."
 
 #: builtin/submodule--helper.c:2225
 #, c-format
 msgid "%s doesn't support --super-prefix"
 msgstr "%s unterstützt kein --super-prefix"
 
 #: builtin/submodule--helper.c:2231
 #, c-format
@@ -18582,33 +18502,39 @@ msgid "expire working trees older than <time>"
 msgstr "Arbeitsverzeichnisse älter als <Zeit> verfallen lassen"
 
 #: builtin/worktree.c:234
 #, c-format
 msgid "'%s' already exists"
 msgstr "'%s' existiert bereits"
 
 #: builtin/worktree.c:251
-#, fuzzy, c-format
+#, c-format
 msgid "unable to re-add worktree '%s'"
-msgstr "konnte \"Tree\"-Objekt (%s) nicht lesen"
+msgstr "Konnte Arbeitsverzeichnis '%s' nicht neu hinzufügen."
 
 #: builtin/worktree.c:256
 #, c-format
 msgid ""
 "'%s' is a missing but locked worktree;\n"
 "use 'add -f -f' to override, or 'unlock' and 'prune' or 'remove' to clear"
 msgstr ""
+"'%s' ist ein fehlendes, aber gesperrtes Arbeitsverzeichnis;\n"
+"Benutzen Sie 'add -f -f' zum Überschrieben, oder 'unlock' und 'prune'\n"
+"oder 'remove' zum Löschen."
 
 #: builtin/worktree.c:258
 #, c-format
 msgid ""
 "'%s' is a missing but already registered worktree;\n"
 "use 'add -f' to override, or 'prune' or 'remove' to clear"
 msgstr ""
+"'%s' ist ein fehlendes, aber bereits registriertes Arbeitsverzeichnis;\n"
+"Benutzen Sie 'add -f' zum Überschreiben, oder 'prune' oder 'remove' zum\n"
+"Löschen."
 
 #: builtin/worktree.c:309
 #, c-format
 msgid "could not create directory of '%s'"
 msgstr "Konnte Verzeichnis '%s' nicht erstellen."
 
 #: builtin/worktree.c:428 builtin/worktree.c:434
 #, c-format
@@ -18702,19 +18628,18 @@ msgstr "'%s' ist nicht gesperrt"
 
 #: builtin/worktree.c:743
 msgid "working trees containing submodules cannot be moved or removed"
 msgstr ""
 "Arbeitsverzeichnisse, die Submodule enthalten, können nicht verschoben oder\n"
 "entfernt werden."
 
 #: builtin/worktree.c:751
-#, fuzzy
 msgid "force move even if worktree is dirty or locked"
-msgstr "Löschen erzwingen, auch wenn das Arbeitsverzeichnis geändert wurde"
+msgstr "Verschieben erzwingen, auch wenn das Arbeitsverzeichnis geändert oder gesperrt ist"
 
 #: builtin/worktree.c:774 builtin/worktree.c:901
 #, c-format
 msgid "'%s' is a main working tree"
 msgstr "'%s' ist ein Hauptarbeitsverzeichnis"
 
 #: builtin/worktree.c:779
 #, c-format
@@ -18722,28 +18647,33 @@ msgid "could not figure out destination name from '%s'"
 msgstr "Konnte Zielname aus '%s' nicht bestimmen."
 
 #: builtin/worktree.c:785
 #, c-format
 msgid "target '%s' already exists"
 msgstr "Ziel '%s' existiert bereits."
 
 #: builtin/worktree.c:793
-#, fuzzy, c-format
+#, c-format
 msgid ""
 "cannot move a locked working tree, lock reason: %s\n"
 "use 'move -f -f' to override or unlock first"
-msgstr "Kann gesperrtes Arbeitsverzeichnis nicht verschieben, Sperrgrund: %s"
+msgstr ""
+"Kann kein gesperrtes Arbeitsverzeichnis verschieben, Sperrgrund: %s\n"
+"Benutzen Sie 'move -f -f' zum Überschreiben oder entsperren Sie zuerst\n"
+"das Arbeitsverzeichnis."
 
 #: builtin/worktree.c:795
-#, fuzzy
 msgid ""
 "cannot move a locked working tree;\n"
 "use 'move -f -f' to override or unlock first"
-msgstr "Kann gesperrtes Arbeitsverzeichnis nicht verschieben, Sperrgrund: %s"
+msgstr ""
+"Kann kein gesperrtes Arbeitsverzeichnis verschieben.\n"
+"Benutzen Sie 'move -f -f' zum Überschreiben oder entsperren Sie zuerst\n"
+"das Arbeitsverzeichnis."
 
 #: builtin/worktree.c:798
 #, c-format
 msgid "validation failed, cannot move working tree: %s"
 msgstr "Validierung fehlgeschlagen, kann Arbeitszeichnis nicht verschieben: %s"
 
 #: builtin/worktree.c:803
 #, c-format
@@ -18761,33 +18691,37 @@ msgid "'%s' is dirty, use --force to delete it"
 msgstr "'%s' ist verändert, benutzen Sie --force zum Löschen"
 
 #: builtin/worktree.c:860
 #, c-format
 msgid "failed to run 'git status' on '%s', code %d"
 msgstr "Fehler beim Ausführen von 'git status' auf '%s'. Code: %d"
 
 #: builtin/worktree.c:883
-#, fuzzy
 msgid "force removal even if worktree is dirty or locked"
-msgstr "Löschen erzwingen, auch wenn das Arbeitsverzeichnis geändert wurde"
+msgstr "Löschen erzwingen, auch wenn das Arbeitsverzeichnis geändert oder gesperrt ist"
 
 #: builtin/worktree.c:906
-#, fuzzy, c-format
+#, c-format
 msgid ""
 "cannot remove a locked working tree, lock reason: %s\n"
 "use 'remove -f -f' to override or unlock first"
-msgstr "Kann gesperrtes Arbeitsverzeichnis nicht löschen, Sperrgrund: %s"
+msgstr ""
+"Kann kein gesperrtes Arbeitsverzeichnis löschen, Sperrgrund: %s\n"
+"Benutzen Sie 'remove -f -f' zum Überschreiben oder entsperren Sie zuerst\n"
+"das Arbeitsverzeichnis."
 
 #: builtin/worktree.c:908
-#, fuzzy
 msgid ""
 "cannot remove a locked working tree;\n"
 "use 'remove -f -f' to override or unlock first"
-msgstr "Kann gesperrtes Arbeitsverzeichnis nicht löschen, Sperrgrund: %s"
+msgstr ""
+"Kann kein gesperrtes Arbeitsverzeichnis löschen.\n"
+"Benutzen Sie 'remove -f -f' zum Überschreiben oder entsperren Sie zuerst\n"
+"das Arbeitsverzeichnis."
 
 #: builtin/worktree.c:911
 #, c-format
 msgid "validation failed, cannot remove working tree: %s"
 msgstr "Validierung fehlgeschlagen, kann Arbeitsverzeichnis nicht löschen: %s"
 
 #: builtin/write-tree.c:14
 msgid "git write-tree [--missing-ok] [--prefix=<prefix>/]"
@@ -18821,24 +18755,23 @@ msgstr ""
 "\n"
 "auszuführen."
 
 #: credential-cache--daemon.c:271
 msgid "print debugging messages to stderr"
 msgstr "Meldungen zur Fehlersuche in Standard-Fehlerausgabe ausgeben"
 
 #: t/helper/test-reach.c:152
-#, fuzzy, c-format
+#, c-format
 msgid "commit %s is not marked reachable"
-msgstr "Commit %s hat keinen Eltern-Commit %d"
+msgstr "Commit %s ist nicht als erreichbar gekennzeichnet."
 
 #: t/helper/test-reach.c:162
-#, fuzzy
 msgid "too many commits marked reachable"
-msgstr "Zu viele Commits zum Schreiben des Graphen."
+msgstr "Zu viele Commits als erreichbar gekennzeichnet."
 
 #: git.c:27
 msgid ""
 "git [--version] [--help] [-C <path>] [-c <name>=<value>]\n"
 "           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
 "           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
 "bare]\n"
 "           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
@@ -18895,17 +18828,17 @@ msgstr "Kein Verzeichnis für -C angegeben.\n"
 #: git.c:300
 #, c-format
 msgid "unknown option: %s\n"
 msgstr "Unbekannte Option: %s\n"
 
 #: git.c:719
 #, c-format
 msgid "alias loop detected: expansion of '%s' does not terminate:%s"
-msgstr ""
+msgstr "Alias-Schleife erkannt: Erweiterung von '%s' schließt nicht ab:%s"
 
 #: git.c:802
 #, c-format
 msgid "expansion of alias '%s' failed; '%s' is not a git command\n"
 msgstr "Erweiterung von Alias '%s' fehlgeschlagen; '%s' ist kein Git-Befehl.\n"
 
 #: git.c:814
 #, c-format
@@ -18923,43 +18856,37 @@ msgstr "Kontrolle über Delegation wird mit cURL < 7.22.0 nicht unterstützt"
 
 #: http.c:404
 msgid "Public key pinning not supported with cURL < 7.44.0"
 msgstr ""
 "Das Anheften des öffentlichen Schlüssels wird mit cURL < 7.44.0\n"
 "nicht unterstützt."
 
 #: http.c:837
-#, fuzzy
 msgid "CURLSSLOPT_NO_REVOKE not suported with cURL < 7.44.0"
-msgstr ""
-"Das Anheften des öffentlichen Schlüssels wird mit cURL < 7.44.0\n"
-"nicht unterstützt."
+msgstr "CURLSSLOPT_NO_REVOKE wird mit cURL < 7.44.0 nicht unterstützt."
 
 #: http.c:910
-#, fuzzy
 msgid "Protocol restrictions not supported with cURL < 7.19.4"
-msgstr ""
-"Das Anheften des öffentlichen Schlüssels wird mit cURL < 7.44.0\n"
-"nicht unterstützt."
+msgstr "Protokollbeschränkungen werden mit cURL < 7.19.4 nicht unterstützt."
 
 #: http.c:1046
 #, c-format
 msgid "Unsupported SSL backend '%s'. Supported SSL backends:"
-msgstr ""
+msgstr "Nicht unterstütztes SSL-Backend '%s'. Unterstützte SSL-Backends:"
 
 #: http.c:1053
 #, c-format
 msgid "Could not set SSL backend to '%s': cURL was built without SSL backends"
-msgstr ""
+msgstr "Konnte SSL-Backend nicht zu '%s' setzen: cURL wurde ohne SSL-Backends gebaut."
 
 #: http.c:1057
-#, fuzzy, c-format
+#, c-format
 msgid "Could not set SSL backend to '%s': already set"
-msgstr "Konnte nicht zu $head_name zurückgehen"
+msgstr "Konnte SSL-Backend nicht zu '%s' setzen: bereits gesetzt"
 
 #: http.c:1921
 #, c-format
 msgid ""
 "unable to update url base from redirection:\n"
 "  asked for: %s\n"
 "   redirect: %s"
 msgstr ""
@@ -19012,19 +18939,18 @@ msgstr "eine Serie von Patches von einer Mailbox anwenden"
 msgid "Annotate file lines with commit information"
 msgstr "Zeilen der Datei mit Commit-Informationen versehen und anzeigen"
 
 #: command-list.h:53
 msgid "Apply a patch to files and/or to the index"
 msgstr "einen Patch auf Dateien und/oder den Index anwenden"
 
 #: command-list.h:54
-#, fuzzy
 msgid "Import a GNU Arch repository into Git"
-msgstr "ein Arch Repository in Git importieren"
+msgstr "ein GNU Arch Repository in Git importieren"
 
 #: command-list.h:55
 msgid "Create an archive of files from a named tree"
 msgstr "Dateiarchiv von angegebenem Verzeichnis erstellen"
 
 #: command-list.h:56
 msgid "Use binary search to find the commit that introduced a bug"
 msgstr ""
@@ -19100,19 +19026,18 @@ msgstr "ein Repository in einem neuen Verzeichnis klonen"
 msgid "Display data in columns"
 msgstr "Daten in Spalten anzeigen"
 
 #: command-list.h:73
 msgid "Record changes to the repository"
 msgstr "Änderungen in das Repository eintragen"
 
 #: command-list.h:74
-#, fuzzy
 msgid "Write and verify Git commit-graph files"
-msgstr "Git Commit Graph-Dateien schreiben und überprüfen"
+msgstr "Git Commit-Graph-Dateien schreiben und überprüfen"
 
 #: command-list.h:75
 msgid "Create a new commit object"
 msgstr "ein neues Commit-Objekt erstellen"
 
 #: command-list.h:76
 msgid "Get and set repository or global options"
 msgstr "repositoryweite oder globale Optionen lesen oder setzen"
@@ -19332,19 +19257,18 @@ msgid "Run merge conflict resolution tools to resolve merge conflicts"
 msgstr ""
 "Ausführen von Tools zur Auflösung von Merge-Konflikten zur Behebung dieser"
 
 #: command-list.h:127
 msgid "Show three-way merge without touching index"
 msgstr "3-Wege-Merge anzeigen ohne den Index zu verändern"
 
 #: command-list.h:128
-#, fuzzy
 msgid "Write and verify multi-pack-indexes"
-msgstr "Git Commit Graph-Dateien schreiben und überprüfen"
+msgstr "multi-pack-indexes schreiben und überprüfen"
 
 #: command-list.h:129
 msgid "Creates a tag object"
 msgstr "ein Tag-Objekt erstellen"
 
 #: command-list.h:130
 msgid "Build a tree-object from ls-tree formatted text"
 msgstr "Tree-Objekt aus ls-tree formattiertem Text erzeugen"
@@ -21338,18 +21262,17 @@ msgstr "Unbekanntes --suppress-cc Feld: '%s'\n"
 #: git-send-email.perl:497
 #, perl-format
 msgid "Unknown --confirm setting: '%s'\n"
 msgstr "Unbekannte --confirm Einstellung: '%s'\n"
 
 #: git-send-email.perl:525
 #, perl-format
 msgid "warning: sendmail alias with quotes is not supported: %s\n"
-msgstr ""
-"Warnung: sendemail Alias mit Anführungsstrichen wird nicht unterstützt: %s\n"
+msgstr "Warnung: sendemail-Alias mit Anführungszeichen wird nicht unterstützt: %s\n"
 
 #: git-send-email.perl:527
 #, perl-format
 msgid "warning: `:include:` not supported: %s\n"
 msgstr "Warnung: `:include:` wird nicht unterstützt: %s\n"
 
 #: git-send-email.perl:529
 #, perl-format
-- 
2.20.0.rc1.379.g1dd7ef354c


^ permalink raw reply related

* Git Test Coverage Report (Friday Nov 30)
From: Derrick Stolee @ 2018-11-30 18:03 UTC (permalink / raw)
  To: Git List

Here is today's test coverage report.

Thanks,
-Stolee

[1] https://dev.azure.com/git/git/_build/results?buildId=277

---

pu: 5a1a9a96d55fbb80426189a921d7b6cc66564c78
jch: 71c29cabb7379fe9abaacbbbd1350268d0c18b4f
next: a9faaff8c120bf4783cb892c157871fe524b3608
master: 7068cbc4abac53d9c3675dfba81c1e97d25e8eeb
master@{1}: 7f4e64169352e03476b0ea64e7e2973669e491a2

Uncovered code in 'pu' not in 'jch'
--------------------------------------

builtin/blame.c
74e8221b52 builtin/blame.c    928) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    929) break;

builtin/remote.c
b7f4e371e7 builtin/remote.c 1551) die(_("--save-to-push cannot be used 
with other options"));
b7f4e371e7 builtin/remote.c 1575) die(_("--save-to-push can only be used 
when only one url is defined"));

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

protocol.c
24c10f7473  37) die(_("Unrecognized protocol version"));
24c10f7473  39) die(_("Unrecognized protocol_version"));

remote-curl.c
24c10f7473  403) return 0;

sha1-array.c
bba406749a 91) oidcpy(&oids[dst], &oids[src]);

strbuf.c
10a40f5700  397) return 0;

submodule.c
e2419f7e30 1376) strbuf_release(&gitdir);
7454fe5cb6 1499) struct get_next_submodule_task *task = task_cb;
7454fe5cb6 1503) get_next_submodule_task_release(task);
7454fe5cb6 1530) return 0;
7454fe5cb6 1534) goto out;
7454fe5cb6 1549) return 0;

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Anders Waldenborg      10a40f570: strbuf: separate callback for 
strbuf_expand:ing literals
Denton Liu      b7f4e371e: remote: add --save-to-push option to git 
remote set-url
Josh Steadmon      24c10f747: protocol: advertise multiple supported 
versions
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Stefan Beller      7454fe5cb: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      bba406749: sha1-array: provide oid_array_filter
Stefan Beller      e2419f7e3: submodule: migrate get_next_submodule to 
use repository structs



Uncovered code in 'jch' not in 'next'
----------------------------------------

apply.c
0f086e6dca 3355) if (checkout_entry(ce, &costate, NULL, NULL) ||
0f086e6dca 3356)     lstat(ce->name, st))

builtin/branch.c
0ecb1fc726 builtin/branch.c 456) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 462) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

hex.c
47edb64997  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
47edb64997  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
47edb64997 116) char *hash_to_hex(const unsigned char *hash)
47edb64997 118) return hash_to_hex_algop(hash, the_hash_algo);

pathspec.c
22af33bece 671) name = to_free = xmemdupz(name, namelen);

read-cache.c
ee70c12820 1730) if (advice_unknown_index_extension) {
ee70c12820 1731) warning(_("ignoring optional %.4s index extension"), ext);
ee70c12820 1732) advise(_("This is likely due to the file having been 
written by a newer\n"

sequencer.c
18e711a162 2387) opts->quiet = 1;

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

tree.c
e092073d64 104) commit = lookup_commit(r, entry.oid);

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      47edb6499: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Elijah Newren      18e711a16: git-rebase, sequencer: extend --quiet 
option for the interactive machinery
Jonathan Nieder      ee70c1282: index: offer advice for unknown index 
extensions
Nguyễn Thái Ngọc Duy      0f086e6dc: checkout: print something when 
checking out paths
Nguyễn Thái Ngọc Duy      22af33bec: dir.c: move, rename and export 
match_attrs()
Nguyễn Thái Ngọc Duy      e092073d6: tree.c: make read_tree*() take 
'struct repository *'



Uncovered code in 'next' not in 'master'
--------------------------------------------

archive.c
c6e7965ddf 399) die(_("not a valid object name: %s"), name);
c6e7965ddf 412) die(_("not a tree object: %s"), oid_to_hex(&oid));
c6e7965ddf 422) die(_("current working directory is untracked"));

attr.c
ad8f8f4aed  369) fprintf_ln(stderr, _("%s not allowed: %s:%d"),

blame.c
fb998eae6c 1717) obj = deref_tag(revs->repo, obj, NULL, 0);
fb998eae6c 1724) head_commit = lookup_commit_reference_gently(revs->repo,

builtin/bundle.c
74ae4b638d builtin/bundle.c 64) return !!unbundle(the_repository, 
&header, bundle_fd, 0) ||

builtin/fast-export.c
b93b81e799 builtin/fast-export.c   52) signed_tag_mode = SIGNED_TAG_ABORT;
b93b81e799 builtin/fast-export.c   70) tag_of_filtered_mode = 
TAG_FILTERING_ABORT;
f129c4275c builtin/fast-export.c  202) if (!p->parents)
f129c4275c builtin/fast-export.c  203) return NULL;
f129c4275c builtin/fast-export.c  204) p = p->parents->item;
f129c4275c builtin/fast-export.c  205) }
843b9e6d48 builtin/fast-export.c  265) die("oid mismatch in blob %s", 
oid_to_hex(oid));
a965bb3116 builtin/fast-export.c  277) printf("original-oid %s\n", 
oid_to_hex(oid));
843b9e6d48 builtin/fast-export.c  356) const unsigned hashsz = 
the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  357) unsigned char *out = 
xcalloc(hashsz, 1);
843b9e6d48 builtin/fast-export.c  358) put_be32(out + hashsz - 4, 
counter++);
843b9e6d48 builtin/fast-export.c  362) static const struct object_id 
*anonymize_oid(const struct object_id *oid)
843b9e6d48 builtin/fast-export.c  365) size_t len = the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  366) return anonymize_mem(&objs, 
generate_fake_oid, oid, &len);
843b9e6d48 builtin/fast-export.c  426) anonymize_oid(&spec->oid) :
a965bb3116 builtin/fast-export.c  644) printf("original-oid %s\n", 
oid_to_hex(&commit->object.oid));
530ca19c02 builtin/fast-export.c  668) printf("%s\n", oid_to_hex(anonymize ?
530ca19c02 builtin/fast-export.c  669) anonymize_oid(&obj->oid) :
f129c4275c builtin/fast-export.c  810) p = rewrite_commit((struct commit 
*)tagged);
f129c4275c builtin/fast-export.c  811) if (!p) {
f129c4275c builtin/fast-export.c  812) printf("reset %s\nfrom %s\n\n",
f129c4275c builtin/fast-export.c  814) free(buf);
f129c4275c builtin/fast-export.c  815) return;
a965bb3116 builtin/fast-export.c  825) printf("original-oid %s\n", 
oid_to_hex(&tag->object.oid));
cd13762d8f builtin/fast-export.c  943) printf("reset %s\nfrom %s\n\n",
cd13762d8f builtin/fast-export.c  945) continue;
530ca19c02 builtin/fast-export.c  960) if (!reference_excluded_commits) {
530ca19c02 builtin/fast-export.c  962) printf("reset %s\nfrom %s\n\n",
530ca19c02 builtin/fast-export.c  964) continue;
530ca19c02 builtin/fast-export.c  967) printf("reset %s\nfrom %s\n\n", name,
530ca19c02 builtin/fast-export.c  968) oid_to_hex(&commit->object.oid));
fdf31b6369 builtin/fast-export.c  969) continue;

builtin/fsck.c
674ba34038 builtin/fsck.c  87) ret = _("unknown");
674ba34038 builtin/fsck.c 167) objerror(parent, _("wrong object type in 
link"));
674ba34038 builtin/fsck.c 278) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
674ba34038 builtin/fsck.c 306) error(_("could not create lost-found"));
674ba34038 builtin/fsck.c 313) die_errno(_("could not write '%s'"), 
filename);
674ba34038 builtin/fsck.c 317) die_errno(_("could not finish '%s'"),
674ba34038 builtin/fsck.c 334) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
674ba34038 builtin/fsck.c 352) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
674ba34038 builtin/fsck.c 371) fprintf_ln(stderr, _("Checking %s %s"),
674ba34038 builtin/fsck.c 384) printf_ln(_("root %s"),
674ba34038 builtin/fsck.c 421) return error(_("%s: object corrupt or 
missing"),
674ba34038 builtin/fsck.c 460) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
674ba34038 builtin/fsck.c 584) error(_("%s: object could not be parsed: 
%s"),
674ba34038 builtin/fsck.c 619) fprintf_ln(stderr, _("Checking object 
directory"));
5215bd2f7d builtin/fsck.c 637) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
5215bd2f7d builtin/fsck.c 642) return error(_("invalid %s"), head_ref_name);
674ba34038 builtin/fsck.c 671) fprintf_ln(stderr, _("Checking cache tree"));
674ba34038 builtin/fsck.c 687) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/merge.c
9440b831ad builtin/merge.c  135) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/pull.c
b19eee9066 647) argv_array_push(&args, opt_cleanup);

builtin/rebase--interactive.c
005af339c9 builtin/rebase--interactive.c  262) ret = 
rearrange_squash(the_repository);
005af339c9 builtin/rebase--interactive.c  265) ret = 
sequencer_add_exec_commands(the_repository, cmd);

builtin/rebase.c
13a5a9f0fd  789) return; /* only override it if it is "rebase" */

builtin/reflog.c
dd509db342 builtin/reflog.c 592) usage(_(reflog_expire_usage));
dd509db342 builtin/reflog.c 643) status |= error(_("%s points 
nowhere!"), argv[i]);
dd509db342 builtin/reflog.c 689) usage(_(reflog_delete_usage));
dd509db342 builtin/reflog.c 695) return error(_("no reflog specified to 
delete"));
dd509db342 builtin/reflog.c 704) status |= error(_("not a reflog: %s"), 
argv[i]);
dd509db342 builtin/reflog.c 709) status |= error(_("no reflog for 
'%s'"), argv[i]);
dd509db342 builtin/reflog.c 744) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 752) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 755) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
c83d950e59 200) die(_("could not start pack-objects to repack promisor 
objects"));
5215bd2f7d 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
c83d950e59 250) die_errno(_("unable to create '%s'"), promisor_name);
5215bd2f7d 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

bundle.c
74ae4b638d 394) struct commit *one = lookup_commit_reference(revs->repo, 
&oid);

delta-islands.c
385cb64ff3 216) parse_object(r, &obj->oid);

fast-import.c
a965bb3116 1821) read_next_command();

git.c
8aa8c14097 341) die_errno(_("while expanding alias '%s': '%s'"),
8aa8c14097 350) die(_("alias '%s' changes environment variables.\n"
8aa8c14097 358) die(_("empty alias for %s"), alias_command);
8aa8c14097 361) die(_("recursive alias: %s"), alias_command);
8aa8c14097 412) die(_("%s doesn't support --super-prefix"), p->cmd);
8aa8c14097 436) die_errno(_("write failure on standard output"));
8aa8c14097 438) die(_("unknown write failure on standard output"));
8aa8c14097 440) die_errno(_("close failed on standard output"));
8aa8c14097 657) die(_("%s doesn't support --super-prefix"), argv[0]);
8aa8c14097 769) die(_("cannot handle %s as a builtin"), cmd);

http-walker.c
b69fb867b4 http-walker.c 550) loose_object_path(the_repository, &buf, 
req->sha1);

http.c
d73019feb4  289) return git_config_string(&curl_http_version, var, value);
d73019feb4  797) static int get_curl_http_version_opt(const char 
*version_string, long *opt)
d73019feb4  808) for (i = 0; i < ARRAY_SIZE(choice); i++) {
d73019feb4  809) if (!strcmp(version_string, choice[i].name)) {
d73019feb4  810) *opt = choice[i].opt_token;
d73019feb4  811) return 0;
d73019feb4  815) warning("unknown value given to http.version: '%s'", 
version_string);
d73019feb4  816) return -1; /* not found */
d73019feb4  841) if (!get_curl_http_version_opt(curl_http_version, &opt)) {
d73019feb4  843) curl_easy_setopt(result, CURLOPT_HTTP_VERSION, opt);

merge-recursive.c
37b65ce36b 1584) return -1;
37b65ce36b 1587) return -1;
37b65ce36b 1593) return -1;
37b65ce36b 1596) return -1;
37b65ce36b 1663) return -1;
37b65ce36b 1666) return -1;
37b65ce36b 1669) return -1;
7f8671656f 1702) return -1;
48c9cb9d6d 1758) return -1;
48c9cb9d6d 1806) return -1;
48c9cb9d6d 1812) return -1;
48c9cb9d6d 1815) return -1;
48c9cb9d6d 1825) return -1;
48c9cb9d6d 1831) return -1;
48c9cb9d6d 1834) return -1;

parse-options-cb.c
9440b831ad  21) return error(_("option `%s' expects a numerical value"),
9440b831ad  51) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
9440b831ad  88) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad  90) return error(_("%s isn't available"), optname(opt, flags));
9440b831ad  92) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad 178) return error(_("%s expects a numerical value"),
9440b831ad 194) return error(_("%s expects a non-negative integer value"
8900342628 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
8900342628 651) error(_("unknown non-ascii option in string: `%s'"),
9440b831ad 785) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

read-cache.c
9d0a9e9089  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
9d0a9e9089  676)     ce->name, alias->name);
9d0a9e9089  691) die(_("cannot create an empty blob in the object 
database"));
9d0a9e9089  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
9d0a9e9089  786) return error(_("unable to add '%s' to index"), path);
9d0a9e9089  822) error(_("invalid path '%s'"), path);
9d0a9e9089  848) error(_("invalid path '%s'"), path);
9d0a9e9089 1686) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
9d0a9e9089 1689) return error(_("bad index version %d"), hdr_version);
9d0a9e9089 1728) return error(_("index uses %.4s extension, which we do 
not understand"),
9d0a9e9089 1730) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
9d0a9e9089 1777) die(_("unknown index entry format 0x%08x"), 
extended_flags);
9d0a9e9089 1848) die(_("unordered stage entries in index"));
9d0a9e9089 1851) die(_("multiple stage entries for merged file '%s'"),
9d0a9e9089 1854) die(_("unordered stage entries for '%s'"),
9d0a9e9089 2148) die_errno(_("%s: index file open failed"), path);
9d0a9e9089 2152) die_errno(_("%s: cannot stat the open index"), path);
9d0a9e9089 2156) die(_("%s: index file smaller than expected"), path);
9d0a9e9089 2160) die_errno(_("%s: unable to map index file"), path);
9d0a9e9089 2251) warning(_("could not freshen shared index '%s'"), 
shared_index);
9d0a9e9089 2286) die(_("broken index, expect %s in %s, got %s"),
9d0a9e9089 3100) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
9d0a9e9089 3247) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
bbfc042ef9  236) oi_deref.info.sizep = &oi_deref.size;
bbfc042ef9  245) return strbuf_addf_ret(err, -1, _("unrecognized 
%%(objectsize) argument: %s"), arg);
ab0e367154  253) return strbuf_addf_ret(err, -1, _("%%(deltabase) does 
not take arguments"));
9440b831ad 2353) return error(_("option `%s' is incompatible with 
--no-merged"),

remote-curl.c
afa5d74929  359) die("invalid server response; expected service, got 
flush packet");

remote.c
0b9c3afdbf  363) warning(_("config remote shorthand cannot begin with 
'/': %s"),
0b9c3afdbf  418) error(_("more than one uploadpack given, using the 
first"));
0b9c3afdbf  684) die(_("key '%s' of pattern had no '*'"), key);
0b9c3afdbf  694) die(_("value '%s' of pattern has no '*'"), value);
0b9c3afdbf 1102) error(_("unable to delete '%s': remote ref does not 
exist"),
0b9c3afdbf 1121) return error(_("dst ref %s receives from more than one 
src"),
0b9c3afdbf 1840) die(_("couldn't find remote ref %s"), name);
0b9c3afdbf 1853) error(_("* Ignoring funny ref '%s' locally"),
0b9c3afdbf 1948) die(_("revision walk setup failed"));
0b9c3afdbf 2221) return error(_("cannot parse expected object name '%s'"),

sequencer.c
f11c958054  593) istate->cache_tree = cache_tree();
f11c958054 3974) res = error_dirty_index(r->index, opts);

sha1-file.c
f0eaf63819 sha1-file.c 2145) return r;

Commits introducing uncovered code:
Denton Liu      b19eee906: merge: add scissors line on merge conflict
Elijah Newren      37b65ce36: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      48c9cb9d6: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      530ca19c0: fast-export: add 
--reference-excluded-parents option
Elijah Newren      7f8671656: merge-recursive: fix rename/add conflict 
handling
Elijah Newren      843b9e6d4: fast-export: convert sha1 to oid
Elijah Newren      a965bb311: fast-export: add a --show-original-ids 
option to show original names
Elijah Newren      b93b81e79: fast-export: use value from correct enum
Elijah Newren      cd13762d8: fast-export: when using paths, avoid 
corrupt stream with non-existent mark
Elijah Newren      f129c4275: fast-export: move commit rewriting logic 
into a function for reuse
Elijah Newren      fdf31b636: fast-export: ensure we export requested refs
Force Charlie      d73019feb: http: add support selecting http version
Jeff King      afa5d7492: remote-curl: refactor smart-http discovery
Jeff King      b69fb867b: sha1_file_name(): overwrite buffer instead of 
appending
Jeff King      f0eaf6381: sha1-file: use an object_directory for the 
main object dir
Johannes Schindelin      13a5a9f0f: rebase: fix GIT_REFLOG_ACTION regression
Junio C Hamano      5215bd2f7: Merge branch 'nd/i18n' into next
Nguyễn Thái Ngọc Duy      005af339c: sequencer.c: remove implicit 
dependency on the_repository
Nguyễn Thái Ngọc Duy      0b9c3afdb: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      385cb64ff: delta-islands.c: remove 
the_repository references
Nguyễn Thái Ngọc Duy      674ba3403: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      74ae4b638: bundle.c: remove the_repository 
references
Nguyễn Thái Ngọc Duy      890034262: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      8aa8c1409: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      9440b831a: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      9d0a9e908: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      ad8f8f4ae: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      c6e7965dd: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      c83d950e5: repack: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      dd509db34: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      f11c95805: sequencer.c: remove implicit 
dependency on the_index
Nguyễn Thái Ngọc Duy      fb998eae6: blame.c: remove implicit dependency 
the_repository
Olga Telezhnaya      ab0e36715: ref-filter: add deltabase option
Olga Telezhnaya      bbfc042ef: ref-filter: add objectsize:disk option



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

transport-helper.c
739fb7167d  576) die(_("unknown response to connect: %s"),

Commits introducing uncovered code:
Nguyễn Thái Ngọc Duy      739fb7167: transport-helper.c: do not 
translate a string twice



^ permalink raw reply

* [PATCH] builtin/rebase.c: remove superfluous space in messages
From: Ralf Thielow @ 2018-11-30 18:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ralf Thielow

Signed-off-by: Ralf Thielow <ralf.thielow@gmail.com>
---
 builtin/rebase.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/builtin/rebase.c b/builtin/rebase.c
index 5b3e5baec8..a6acba76b4 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -871,7 +871,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
 			       "them"), REBASE_PRESERVE_MERGES),
 		OPT_BOOL(0, "rerere-autoupdate",
 			 &options.allow_rerere_autoupdate,
-			 N_("allow rerere to update index  with resolved "
+			 N_("allow rerere to update index with resolved "
 			    "conflict")),
 		OPT_BOOL('k', "keep-empty", &options.keep_empty,
 			 N_("preserve empty commits during rebase")),
@@ -1520,7 +1520,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
 	 */
 	strbuf_reset(&msg);
 	if (!oidcmp(&merge_base, &options.orig_head)) {
-		printf(_("Fast-forwarded %s to %s. \n"),
+		printf(_("Fast-forwarded %s to %s.\n"),
 			branch_name, options.onto_name);
 		strbuf_addf(&msg, "rebase finished: %s onto %s",
 			options.head_name ? options.head_name : "detached HEAD",
-- 
2.20.0.rc1.379.g1dd7ef354c


^ permalink raw reply related

* Re: [PATCH] builtin/rebase.c: remove superfluous space in messages
From: Johannes Schindelin @ 2018-11-30 18:52 UTC (permalink / raw)
  To: Ralf Thielow; +Cc: git, Junio C Hamano
In-Reply-To: <20181130181145.13539-1-ralf.thielow@gmail.com>

Hi Ralf,

On Fri, 30 Nov 2018, Ralf Thielow wrote:

> Signed-off-by: Ralf Thielow <ralf.thielow@gmail.com>

ACK.

The commit message could state that the scripted rebase does not have
those whitespace issues, and that this aligns the built-in rebase with it,
but I won't insist.

Ciao,
Johannes

> ---
>  builtin/rebase.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/builtin/rebase.c b/builtin/rebase.c
> index 5b3e5baec8..a6acba76b4 100644
> --- a/builtin/rebase.c
> +++ b/builtin/rebase.c
> @@ -871,7 +871,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
>  			       "them"), REBASE_PRESERVE_MERGES),
>  		OPT_BOOL(0, "rerere-autoupdate",
>  			 &options.allow_rerere_autoupdate,
> -			 N_("allow rerere to update index  with resolved "
> +			 N_("allow rerere to update index with resolved "
>  			    "conflict")),
>  		OPT_BOOL('k', "keep-empty", &options.keep_empty,
>  			 N_("preserve empty commits during rebase")),
> @@ -1520,7 +1520,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
>  	 */
>  	strbuf_reset(&msg);
>  	if (!oidcmp(&merge_base, &options.orig_head)) {
> -		printf(_("Fast-forwarded %s to %s. \n"),
> +		printf(_("Fast-forwarded %s to %s.\n"),
>  			branch_name, options.onto_name);
>  		strbuf_addf(&msg, "rebase finished: %s onto %s",
>  			options.head_name ? options.head_name : "detached HEAD",
> -- 
> 2.20.0.rc1.379.g1dd7ef354c
> 
> 

^ permalink raw reply

* Re: [PATCH v3 06/16] sequencer: refactor sequencer_add_exec_commands() to work on a todo_list
From: Johannes Schindelin @ 2018-11-30 19:06 UTC (permalink / raw)
  To: phillip.wood; +Cc: Alban Gruin, git, Junio C Hamano
In-Reply-To: <0e00acd9-5b09-b712-2e21-550e348ea0df@talktalk.net>

Hi,

On Fri, 30 Nov 2018, Phillip Wood wrote:

> > diff --git a/sequencer.c b/sequencer.c
> > index 900899ef20..11692d0b98 100644
> > --- a/sequencer.c
> > +++ b/sequencer.c
> > @@ -4394,24 +4394,29 @@ int sequencer_make_script(FILE *out, int argc, const
> > char **argv,
> >  	return 0;
> >  }
> >  
> > -/*
> > - * Add commands after pick and (series of) squash/fixup commands
> > - * in the todo list.
> > - */
> > -int sequencer_add_exec_commands(const char *commands)
> > +static void todo_list_add_exec_commands(struct todo_list *todo_list,
> > +					struct string_list *commands)
> > {
> > -	const char *todo_file = rebase_path_todo();
> > -	struct todo_list todo_list = TODO_LIST_INIT;
> > -	struct strbuf *buf = &todo_list.buf;
> > -	size_t offset = 0, commands_len = strlen(commands);
> > -	int i, insert;
> > +	struct strbuf *buf = &todo_list->buf;
> > +	const char *old_buf = buf->buf;
> > +	size_t base_length = buf->len;
> > +	int i, insert, nr = 0, alloc = 0;
> > +	struct todo_item *items = NULL, *base_items = NULL;
> > 
> > -	if (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)
> > -		return error(_("could not read '%s'."), todo_file);
> > +	for (i = 0; i < commands->nr; ++i) {
> > +		strbuf_addstr(buf, commands->items[i].string);
> > +		strbuf_addch(buf, '\n');
> > +	}
> 
> This could cause buf->buf to be reallocated in which case all the
> todo_list_item.arg pointers will be invalidated.

I guess it is a good time for me to admit that the `arg` idea was not my
best. Maybe it would be good to convert that from a pointer to an offset,
e.g. `size_t arg_offset_in_buf;`? Or maybe we should just drop the
`_in_buf` suffix and clarify in a comment next to the declaration of the
fields that they are offsets in the strbuf?

Ciao,
Dscho

^ permalink raw reply

* [RFC PATCH v3] technical doc: add a design doc for the evolve command
From: sxenos @ 2018-12-01  0:52 UTC (permalink / raw)
  To: git; +Cc: sbeller, jrn, jch, jonathantanmy, stolee, carl, dborowitz,
	Stefan Xenos

From: Stefan Xenos <sxenos@google.com>

This document describes what a change graph for
git would look like, the behavior of the evolve command,
and the changes planned for other commands.

Signed-off-by: Stefan Xenos <sxenos@google.com>
---
 Documentation/technical/evolve.txt | 1000 ++++++++++++++++++++++++++++
 1 file changed, 1000 insertions(+)
 create mode 100644 Documentation/technical/evolve.txt

diff --git a/Documentation/technical/evolve.txt b/Documentation/technical/evolve.txt
new file mode 100644
index 0000000000..bfec6fcf82
--- /dev/null
+++ b/Documentation/technical/evolve.txt
@@ -0,0 +1,1000 @@
+Evolve
+======
+
+Objective
+=========
+Create an "evolve" command to help users craft a high quality commit history.
+Users can improve commits one at a time and in any order, then run git evolve to
+rewrite their recent history to ensure everything is up-to-date. We track
+amendments to a commit over time in a change graph. Users can share their
+progress with others by exchanging their change graphs using the standard push,
+fetch, and format-patch commands.
+
+Status
+======
+This proposal has not been implemented yet.
+
+Background
+==========
+Imagine you have three sequential changes up for review and you receive feedback
+that requires editing all three changes. We'll define the word "change"
+formally later, but for the moment let's say that a change is a work-in-progress
+whose final version will be submitted as a commit in the future.
+
+While you're editing one change, more feedback arrives on one of the others.
+What do you do?
+
+The evolve command is a convenient way to work with chains of commits that are
+under review. Whenever you rebase or amend a commit, the repository remembers
+that the old commit is obsolete and has been replaced by the new one. Then, at
+some point in the future, you can run "git evolve" and the correct sequence of
+rebases will occur in the correct order such that no commit has an obsolete
+parent.
+
+Part of making the "evolve" command work involves tracking the edits to a commit
+over time, which is why we need an change graph. However, the change
+graph will also bring other benefits:
+
+- Users can view the history of a change directly (the sequence of amends and
+  rebases it has undergone, orthogonal to the history of the branch it is on).
+- It will be possible to quickly locate and list all the changes the user
+  currently has in progress.
+- It can be used as part of other high-level commands that combine or split
+  changes.
+- It can be used to decorate commits (in git log, gitk, etc) that are either
+  obsolete or are the tip of a work in progress.
+- By pushing and pulling the change graph, users can collaborate more
+  easily on changes-in-progress. This is better than pushing and pulling the
+  changes themselves since the change graph can be used to locate a more
+  specific merge base, allowing for better merges between different versions of
+  the same change. 
+- It could be used to correctly rebase local changes and other local branches
+  after running git-filter-branch.
+- It can replace the change-id footer used by gerrit.
+
+Goals
+-----
+Legend: Goals marked with P0 are required. Goals marked with Pn should be
+attempted unless they interfere with goals marked with Pn-1.
+
+P0. All commands that modify commits (such as the normal commit --amend or
+    rebase command) should mark the old commit as being obsolete and replaced by
+    the new one. No additional commands should be required to keep the
+    change graph up-to-date.
+P0. Any commit that may be involved in a future evolve command should not be
+    garbage collected. Specifically:
+    - Commits that obsolete another should not be garbage collected until
+      user-specified conditions have occurred and the change has expired from
+      the reflog. User specified conditions for removing changes include:
+      - The user explicitly deleted the change.
+      - The change was merged into a specific branch.
+    - Commits that have been obsoleted by another should not be garbage
+      collected if any of their replacements are still being retained.
+P0. A commit can be obsoleted by more than one replacement (called divergence).
+P0. Must be able to resolve divergence (convergence).
+P1. Users should be able to share chains of obsolete changes in order to
+    collaborate on WIP changes.
+P2. Such sharing should be at the user’s option. That is, it should be possible
+    to directly share a change without also sharing the file states or commit
+    comments from the obsolete changes that led up to it, and the choice not to
+    share those commits should not require changing any commit hashes.
+P2. It should be possible to discard part or all of the change graph
+    without discarding the commits themselves that are already present in
+    branches and the reflog.
+P2. Provide sufficient information to replace gerrit's Change-Id footers.
+
+Similar technologies
+--------------------
+There are some other technologies that address the same end-user problem.
+
+Rebase -i can be used to solve the same problem, but users can't easily switch
+tasks midway through an interactive rebase or have more than one interactive
+rebase going on at the same time. It can't handle the case where you have
+multiple changes sharing the same parent when that parent needs to be rebased
+and won't let you collaborate with others on resolving a complicated interactive
+rebase. You can think of rebase -i as a top-down approach and the evolve command
+as the bottom-up approach to the same problem.
+
+Several patch queue managers have been built on top of git (such as topgit,
+stgit, and quilt). They address the same user need. However they also rely on
+state managed outside git that needs to be kept in sync. Such state can be
+easily damaged when running a git native command that is unaware of the patch
+queue. They also typically require an explicit initialization step to be done by
+the user which creates workflow problems.
+
+Mercurial implements a very similar feature in its EvolveExtension. The behavior
+of the evolve command itself is very similar, but the storage format for the
+change graph differs. In the case of mercurial, each change set can have one or
+more obsolescence markers that point to other changesets that they replace. This
+is similar to the "Commit Headers" approach considered in the other options
+appendix. The approach proposed here stores obsolescence information in a
+separate metacommit graph, which makes exchanging of obsolescence information
+optional.
+
+Mercurial's default behavior makes it easy to find and switch between
+non-obsolete changesets that aren't currently on any branch. We introduce the
+notion of a new ref namespace that enables a similar workflow via a different
+mechanism. Mercurial has the notion of changeset phases which isn't present
+in git and creates new ways for a changeset to diverge. Git doesn't need
+to deal with these issues, but it has to deal with picking an upstream branch as
+a target for rebases and protecting obsolescence information from GC. We also
+introduce some additional transformations (see obsolescence-over-cherry-pick,
+below) that aren't present in the mercurial implementation.
+
+Semi-related work
+-----------------
+There are other technologies that address different problems but have some
+similarities with this proposal.
+
+Replacements (refs/replace) are superficially similar to obsolescences in that
+they describe that one commit should be replaced by another. However, they
+differ in both how they are created and how they are intended to be used.
+Obsolescences are created automatically by the commands a user runs, and they
+describe the user’s intent to perform a future rebase. Obsolete commits still
+appear in branches, logs, etc like normal commits (possibly with an extra
+decoration that marks them as obsolete). Replacements are typically created
+explicitly by the user, they are meant to be kept around for a long time, and
+they describe a replacement to be applied at read-time rather than as the input
+to a future operation. When a replaced commit is queried, it is typically hidden
+and swapped out with its replacement as though the replacement has already
+occurred.
+
+Git-imerge is a project to help make complicated merges easier, particularly
+when merging or rebasing long chains of patches. It is not an alternative to
+the change graph, but its algorithm of applying smaller incremental merges
+could be used as part of the evolve algorithm in the future.
+
+Overview
+========
+We introduce the notion of “meta-commits” which describe how one commit was
+created from other commits. A branch of meta-commits is known as a change.
+Changes are created and updated automatically whenever a user runs a command
+that creates a commit. They are used for locating obsolete commits, providing a
+list of a user’s unsubmitted work in progress, and providing a stable name for
+each unsubmitted change.
+
+Users can exchange edit histories by pushing and fetching changes.
+
+New commands will be introduced for manipulating changes and resolving
+divergence between them. Existing commands that create commits will be updated
+to modify the meta-commit graph and create changes where necessary.
+
+Example usage
+-------------
+# First create three dependent changes
+$ echo foo>bar.txt && git add .
+$ git commit -m "This is a test"
+created change metas/this_is_a_test
+$ echo foo2>bar2.txt && git add .
+$ git commit -m "This is also a test"
+created change metas/this_is_also_a_test
+$ echo foo3>bar3.txt && git add .
+$ git commit -m "More testing"
+created change metas/more_testing
+
+# List all our changes in progress
+$ git change -l
+metas/this_is_a_test
+metas/this_is_also_a_test
+* metas/more_testing
+metas/some_change_already_merged_upstream
+
+# Now modify the earliest change, using its stable name
+$ git reset --hard metas/this_is_a_test
+$ echo morefoo>>bar.txt && git add . && git commit --amend --no-edit
+
+# Use git-evolve to fix up any dependent changes
+$ git evolve
+rebasing metas/this_is_also_a_test onto metas/this_is_a_test
+rebasing metas/more_testing onto metas/this_is_also_a_test
+Done
+
+# Use git-obslog to view the history of the this_is_a_test change
+$ git obslog
+93f110 metas/this_is_a_test@{0} commit (amend): This is a test
+930219 metas/this_is_a_test@{1} commit: This is a test
+
+# Now create an unrelated change
+$ git reset --hard origin/master
+$ echo newchange>unrelated.txt && git add .
+$ git commit -m "Unrelated change"
+created change metas/unrelated_change
+
+# Fetch the latest code from origin/master and use git-evolve
+# to rebase all dependent changes.
+$ git fetch origin master
+$ git evolve origin/master
+deleting metas/some_change_already_merged_upstream
+rebasing metas/this_is_a_test onto origin/master
+rebasing metas/this_is_also_a_test onto metas/this_is_a_test
+rebasing metas/more_testing onto metas/this_is_also_a_test
+rebasing metas/unrelated_change onto origin/master
+Conflict detected! Resolve it and then use git evolve --continue to resume.
+
+# Sort out the conflict
+$ git mergetool
+$ git evolve --continue
+Done
+
+# Share the full history of edits for the this_is_a_test change
+# with a review server
+$ git push origin metas/this_is_a_test:refs/for/master
+# Share the lastest commit for “Unrelated change”, without history
+$ git push origin HEAD:refs/for/master
+
+Detailed design
+===============
+Obsolescence information is stored as a graph of meta-commits. A meta-commit is
+a specially-formatted merge commit that describes how one commit was created
+from others.
+
+Meta-commits look like this:
+
+$ git cat-file -p <example_meta_commit>
+tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904
+parent aa7ce55545bf2c14bef48db91af1a74e2347539a
+parent d64309ee51d0af12723b6cb027fc9f195b15a5e9
+parent 7e1bbcd3a0fa854a7a9eac9bf1eea6465de98136
+author Stefan Xenos <sxenos@gmail.com> 1540841596 -0700
+committer Stefan Xenos <sxenos@gmail.com> 1540841596 -0700
+parent-type content
+parent-type obsolete
+parent-type origin
+
+This says “commit aa7ce555 makes commit d64309ee obsolete. It was created by
+cherry-picking commit 7e1bbcd3”.
+
+The tree for meta-commits is always the empty tree whose hash matches
+4b825dc642cb6eb9a060e54bf8d69288fbee4904 exactly, but future versions of git may
+attach other trees here. For forward-compatibility fsck should ignore such trees
+if found on future repository versions. Similarly, current versions of git
+should always fill in an empty commit comment and tools like fsck should ignore
+the content of the commit comment if present in a future repository version.
+This will allow future versions of git to add metadata to the meta-commit
+comments or tree without breaking forwards compatibility.
+
+Parent-type
+-----------
+The “parent-type” field in the commit header identifies a commit as a
+meta-commit and indicates the meaning for each of its parents. It is never
+present for normal commits. It is a list of enum values whose order matches the
+order of the parents. Possible parent types are:
+
+- content: the content parent identifies the commit that this meta-commit is
+  describing.
+- obsolete: indicates that this parent is made obsolete by the content parent.
+- origin: indicates that this parent was generated from the given commit.
+
+There must be exactly one content parent for each meta-commit and it is always
+the first parent. The content commit will always be a normal commit and not a
+meta-commit. However, future versions of git may create meta-commits for other
+meta-commits and the fsck tool must be aware of this for forwards compatibility.
+
+A meta-commit can have zero or more obsolete parents. An amend operation creates
+a single obsolete parent. A merge used to resolve divergence (see divergence,
+below) will create multiple obsolete parents. A meta-commit may have no
+obsolete parents if it describes a cherry-pick or squash merge that copies one
+or more commits but does not replace them.
+
+A meta-commit can have zero or more origin parents. A cherry-pick creates a
+single origin parent. Certain types of squash merge will create multiple origin
+parents. Origin parents don't directly cause their origin to become obsolete,
+but are used when computing blame or locating a merge base. The section
+on obsolescence over cherry-picks describes how the evolve command uses
+origin parents.
+
+An obsolete parent or origin parent may be either a normal commit (indicating
+the oldest-known version of a change) or another meta-commit (for a change that
+has already been modified one or more times).
+
+The parent-type field needs to go after the committer field since git's rules
+for forwards-compatibility require that new fields to be at the end of the
+header. Putting a new field in the middle of the header would break fsck. 
+
+Changes
+-------
+A branch of meta-commits describes how a commit was produced and what previous
+commits it is based on. It is also an identifier for a thing the user is
+currently working on. We refer to such a meta-branch as a change.
+
+Local changes are stored in the new refs/metas namespace. Remote changes are
+stored in the refs/remote/<remotename>/metas namespace.
+
+The list of changes in refs/metas is more than just a mechanism for the evolve
+command to locate obsolete commits. It is also a convenient list of all of a
+user’s work in progress and their current state - a list of things they’re
+likely to want to come back to.
+
+Strictly speaking, it is the presence of the branch in the refs/metas namespace
+that marks a branch as being a change, not the fact that it points to a
+metacommit. Metacommits are only created when a commit is amended or rebased, so
+in the case where a change points to a commit that has never been modified, the
+change points to that initial commit rather than a metacommit.
+
+Obsolescence
+------------
+A commit is considered obsolete if it is reachable from the “replaces” edges
+anywhere in the history of a change and it isn’t the head of that change.
+Commits may be the content for 0 or more meta-commits. If the same commit
+appears in multiple changes, it is not obsolete if it is the head of any of
+those changes.
+
+Divergence
+----------
+From the user’s perspective, two changes are divergent if they both ask for
+different replacements to the same commit. More precisely, a target commit is
+considered divergent if there is more than one commit at the head of a change in
+refs/metas that leads to the target commit via an unbroken chain of “obsolete”
+parents.
+
+Much like a merge conflict, divergence is a situation that requires user
+intervention to resolve. The evolve command will stop when it encounters
+divergence and prompt the user to resolve the problem. Users can solve the
+problem in several ways:
+
+- Discard one of the changes (by deleting its change branch).
+- Merge the two changes (producing a single change branch).
+- Copy one of the changes (keep both commits, but one of them gets a new
+  metacommit appended to its history that is connected to its predecessor via an
+  origin edge rather than an obsolete edge. That new change no longer obsoletes
+  the original.)
+
+Obsolescence across cherry-picks
+--------------------------------
+By default the evolve command will treat cherry-picks and squash merges as being
+completely separate from the original. Further amendments to the original commit
+will have no effect on the cherry-picked copy. However, this behavior may not be
+desirable in all circumstances.
+
+The evolve command may at some point support an option to look for cases where
+the source of a cherry-pick or squash merge has itself been amended, and
+automatically apply that same change to the cherry-picked copy. In such cases,
+it would traverse origin edges rather than ignoring them, and would treat a
+commit with origin edges as being obsolete if any of its origins were obsolete.
+
+Garbage collection
+------------------
+For GC purposes, meta-commits are normal commits. Just as a commit causes its
+parents and tree to be retained, a meta-commit also causes its parents to be
+retained.
+
+Change creation
+---------------
+Changes are created automatically whenever the user runs a command like “commit”
+that has the semantics of creating a new change. They also move forward
+automatically even if they’re not checked out. For example, whenever the user
+runs a command like “commit --amend” that modifies a commit, all branches in
+refs/metas that pointed to the old commit move forward to point to its
+replacement instead. This also happens when the user is working from a detached
+head.
+
+This does not mean that every commit has a corresponding change. By default,
+changes only exist for recent locally-created commits. Users may explicitly pull
+changes from other users or keep their changes around for a long time, but
+either behavior requires a user to opt-in. Code review systems like gerrit may
+also choose to keep changes around forever.
+
+Note that the changes in refs/metas serve a dual function as both a way to
+identify obsolete changes and as a way for the user to keep track of their work
+in progress. If we were only concerned with identifying obsolete changes, it
+would be sufficient to create the change branch lazily the first time a commit
+is obsoleted. Addressing the second use - of refs/metas as a mechanism for
+keeping track of work in progress - is the reason for eagerly creating the
+change on first commit.
+
+Change naming
+-------------
+When a change is first created, the only requirement for its name is that it
+must be unique. Good names would also serve as useful mnemonics and be easy to
+type. For example, a short word from the commit message containing no numbers or
+special characters and that shows up with low frequency in other commit messages
+would make a good choice.
+
+Different users may prefer different heuristics for their change names. For this
+reason a new hook will be introduced to compute change names. Git will invoke
+the hook for all newly-created changes and will append a numeric suffix if the
+name isn’t unique. The default heuristics are not specified by this proposal and
+may change during implementation.
+
+Change deletion
+---------------
+Changes are normally only interesting to a user while a commit is still in
+development and under review. Once the commit has submitted wherever it is
+going, its change can be discarded.
+
+The normal way of deleting changes makes this easy to do - changes are deleted
+by the evolve command when it detects that the change is present in an upstream
+branch. It does this in two ways: if the latest commit in a change either shows
+up in the branch history or the change becomes empty after a rebase, it is
+considered merged and the change is discarded. In this context, an “upstream
+branch” is any branch passed in as the upstream argument of the evolve command.
+
+In case this sometimes deletes a useful change, such automatic deletions are
+recorded in the reflog allowing them to be easily recovered.
+
+Sharing changes
+---------------
+Change histories are shared by pushing or fetching meta-commits and change
+branches. This provides users with a lot of control of what to share and
+repository implementations with control over what to retain.
+
+Users that only want to share the content of a commit can do so by pushing the
+commit itself as they currently would. Users that want to share an edit history
+for the commit can push its change, which would point to a meta-commit rather
+than the commit itself if there is any history to share. Note that multiple
+changes can refer to the same commits, so it’s possible to construct and push a
+different history for the same commit in order to remove sensitive or irrelevant
+intermediate states.
+
+Imagine the user is working on a change “mychange” that is currently the latest
+commit on master, they have two ways to share it:
+
+# User shares just a commit without its history
+> git push origin master
+
+# User shares the full history of the commit to a review system
+> git push origin metas/mychange:refs/for/master
+
+# User fetches a collaborator’s modifications to their change
+> git fetch remotename metas/mychange
+# Which updates the ref remote/remotename/metas/mychange
+
+This will cause more intermediate states to be shared with the server than would
+have been shared previously. A review system like gerrit would need to keep
+track of which states had been explicitly pushed versus other intermediate
+states in order to de-emphasize (or hide) the extra intermediate states from the
+user interface.
+
+Merge-base
+----------
+Merge-base will be changed to search the meta-commit graph for common ancestors
+as well as the commit graph, and will generally prefer results from the
+meta-commit graph over the commit graph. Merge-base will consider meta-commits
+from all changes, and will traverse both origin and obsolete edges.
+
+The reason for this is that - when merging two versions of the same commit
+together - an earlier version of that same commit will usually be much more
+similar than their common parent. This should make the workflow of collaborating
+on unsubmitted patches as convenient as the workflow for collaborating in a
+topic branch by eliminating repeated merges.
+
+Configuration
+-------------
+The core.enableChanges configuration variable enables the creation and update
+of change branches. This is enabled by default.
+
+User interface
+--------------
+All git porcelain commands that create commits are classified as having one of
+four behaviors: modify, create, copy, or import. These behaviors are discussed
+in more detail below.
+
+Modify commands
+---------------
+Modification commands (commit --amend, rebase) will mark the old commit as
+obsolete by creating a new meta-commit that references the old one as an
+obsolete parent. In the event that multiple changes point to the same commit,
+this is done independently for every such change.
+
+More specifically, modifications work like this:
+
+1. Locate all existing changes for which the old commit is the content for the
+   head of the change branch. If no such branch exists, create one that points
+   to the old commit. Changes that include this commit in their history but not
+   at their head are explicitly not included.
+2. For every such change, create a new meta-commit that references the new
+   commit as its content and references the old head of the change as an
+   obsolete parent.
+3. Move the change branch forward to point to the new meta-commit.
+
+Copy commands
+-------------
+Copy commands (cherry-pick, merge --squash) create a new meta-commit that
+references the old commits as origin parents. Besides the fact that the new
+parents are tagged differently, copy commands work the same way as modify
+commands.
+
+Create commands
+---------------
+Creation commands (commit, merge) create a new commit and a new change that
+points to that commit. The do not create any meta-commits.
+
+Import commands
+---------------
+Import commands (fetch, pull) do not create any new meta-commits or changes
+unless that is specifically what they are importing. For example, the fetch
+command would update remote/origin/metas/change35 and fetch all referenced
+meta-commits if asked to do so directly, but it wouldn’t create any changes or
+meta-commits for commits discovered on the master branch when running “git fetch
+origin master”.
+
+Other commands
+--------------
+Some commands don’t fit cleanly into one of the above categories.
+
+Semantically, filter-branch should be treated as a modify command, but doing so
+is likely to create a lot of irrelevant clutter in the changes namespace and the
+large number of extra change refs may introduce performance problems. We
+recommend treating filter-branch as an import command initially, but making it
+behave more like a modify command in future follow-up work. One possible
+solution may be to treat commits that are part of existing changes as being
+modified but to avoid creating changes for other rewritten changes.
+
+Once the evolve command can handle obsolescence across cherry-picks, such
+cherry-picks will result in a hybrid move-and-copy operation. It will create
+cherry-picks that replace other cherry-picks, which will have both origin edges
+(pointing to the new source commit being picked) and obsolete edges (pointing to
+the previous cherry-pick being replaced).
+
+Evolve
+------
+The evolve command performs the correct sequence of rebases such that no change
+has an obsolete parent. The syntax looks like this:
+
+git evolve [--abort][--continue][--quit] [upstream…]
+
+It takes an optional list of upstream branches. All changes whose parent shows
+up in the history of one of the upstream branches will be rebased onto the
+upstream branch before resolving obsolete parents.
+
+Any change whose latest state is found in an upstream branch (or that ends up
+empty after rebase) will be deleted. This is the normal mechanism for deleting
+changes. Changes are created automatically on the first commit, and are deleted
+automatically when evolve determines that they’ve been merged upstream.
+
+Orphan commits are commits with obsolete parents. The evolve command then
+repeatedly rebases orphan commits with non-orphan parents until there are either
+no orphan commits left, a merge conflict is discovered, or a divergent parent is
+discovered.
+
+When evolve discovers divergence, it will first check if it can resolve the
+divergence automatically using one of its enabled transformations. Supported
+transformations are:
+
+- Check if the user has already merged the divergent changes in a follow-up
+  change. That is, look for an existing merge in a follow-up change where all
+  the parents are divergent versions of the same change. Squash that merge with
+  its parents and use the result as the resolution for the divergence.
+
+- Attempt to auto-merge all the divergent changes (disabled by default).
+
+Each of the transformations can be enabled or disabled by command line options.
+
+The --abort option returns all changes to the state they were in prior to
+invoking evolve, and the --quit option terminates the current evolution without
+changing the current state.
+
+If the working tree is dirty, evolve will attempt to stash the user's changes
+before applying the evolve and then reapply those changes afterward, in much
+the same way as rebase --autostash does.
+
+Checkout
+--------
+Running checkout on a change by name has the same effect as checking out a
+detached head pointing to the latest commit on that change-branch. There is no
+need to ever have HEAD point to a change since changes always move forward when
+necessary, no matter what branch the user has checked out
+
+Meta-commits themselves cannot be checked out by their hash.
+
+Reset
+-----
+Resetting a branch to a change by name is the same as resetting to the commit at
+that change’s head.
+
+Commit
+------
+Commit --amend gets modify semantics and will move existing changes forward. The
+normal form of commit gets create semantics and will create a new change.
+
+$ touch foo && git add . && git commit -m "foo" && git tag A
+$ touch bar && git add . && git commit -m "bar" && git tag B
+$ touch baz && git add . && git commit -m "baz" && git tag C
+
+This produces the following commits:
+A(tree=[foo])
+B(tree=[foo, bar], parent=A)
+C(tree=[foo, bar, baz], parent=B)
+
+...along with three changes:
+metas/foo = A
+metas/bar = B
+metas/baz = C
+
+Running commit --amend does the following:
+$ git checkout B
+$ touch zoom && git add . && git commit --amend -m "baz and zoom"
+$ git tag D
+
+Commits:
+A(tree=[foo])
+B(tree=[foo, bar], parent=A)
+C(tree=[foo, bar, baz], parent=B)
+D(tree=[foo, bar, zoom], parent=A)
+Dmeta(content=D, obsolete=B)
+
+Changes:
+metas/foo = A
+metas/bar = Dmeta
+metas/baz = C
+
+Merge
+-----
+Merge gets create, modify, or copy semantics based on what is being merged and
+the options being used.
+
+The --squash version of merge gets copy semantics (it produces a new change that
+is marked as a copy of all the original changes that were squashed into it).
+
+The “modify” version of merge replaces both of the original commits with the
+resulting merge commit. This is one of the standard mechanisms for resolving
+divergence. The parents of the merge commit are the parents of the two commits
+being merged. The resulting commit will not be a merge commit if both of the
+original commits had the same parent or if one was the parent of the other.
+
+The “create” version of merge creates a new change pointing to a merge commit
+that has both original commits as parents. The result is what merge produces now
+- a new merge commit. However, this version of merge doesn’t directly resolve
+divergence.
+
+To select between these two behaviors, merge gets new “--amend” and “--noamend”
+options which select between the “create” and “modify” behaviors respectively,
+with noamend being the default.
+
+For example, imagine we created two divergent changes like this:
+
+$ touch foo && git add . && git commit -m "foo" && git tag A
+$ touch bar && git add . && git commit -m "bar" && git tag B
+$ touch baz && git add . && git commit --amend -m "bar and baz"
+$ git tag C
+$ git checkout B
+$ touch bam && git add . && git commit --amend -m "bar and bam"
+$ git tag D
+
+At this point the commit graph looks like this:
+
+A(tree=[foo])
+B(tree=[bar], parent=A)
+C(tree=[bar, baz], parent=A)
+D(tree=[bar, bam], parent=A)
+Cmeta(content=C, obsoletes=B)
+Dmeta(content=D, obsoletes=B)
+
+There would be three active changes with heads pointing as follows:
+
+metas/changeA=A
+metas/changeB=Cmeta
+metas/changeB2=Dmeta
+
+ChangeB and changeB2 are divergent at this point. Lets consider what happens if
+perform each type of merge between changeB and changeB2.
+
+Merge example: Amend merge
+One way to resolve divergent changes is to use an amend merge. Recall that HEAD
+is currently pointing to D at this point.
+
+$ git merge --amend metas/changeB
+
+Here we’ve asked for an amend merge since we’re trying to resolve divergence
+between two versions of the same change. There are no conflicts so we end up
+with this:
+
+E(tree=[bar, baz, bam], parent=A)
+Emeta(content=E, obsoletes=[Cmeta, Dmeta])
+
+With the following branches:
+
+metas/changeA=A
+metas/changeB=Emeta
+metas/changeB2=Emeta
+
+Notice that the result of the “amend merge” is a replacement for C and D rather
+than a new commit with C and D as parents (as a normal merge would have
+produced). The parents of the amend merge are the parents of C and D which - in
+this case - is just A, so the result is not a merge commit. Also notice that
+changeB and changeB2 are now aliases for the same change.
+
+Merge example: Noamend merge
+Consider what would have happened if we’d used a noamend merge instead. Recall
+that HEAD was at D and our branches looked like this:
+
+metas/changeA=A
+metas/changeB=Cmeta
+metas/changeB2=Dmeta
+
+$ git merge --noamend metas/changeB
+
+That would produce the sort of merge we’d normally expect today:
+
+F(tree=[bar, baz, bam], parent=[C, D])
+
+And our changes would look like this:
+metas/changeA=A
+metas/changeB=Cmeta
+metas/changeB2=Dmeta
+metas/changeF=F
+
+In this case, changeB and changeB2 are still divergent and we’ve created a new
+change for our merge commit. However, this is just a temporary state. The next
+time we run the “evolve” command, it will discover the divergence but also
+discover the merge commit F that resolves it. Evolve will suggest converting F
+into an amend merge in order to resolve the divergence and will display the
+command for doing so.
+
+Rebase
+------
+In general the rebase command is treated as a modify command. When a change is
+rebased, the new commit replaces the original.
+
+Rebase --abort is special. Its intent is to restore git to the state it had
+prior to running rebase. It should move back any changes to point to the refs
+they had prior to running rebase and delete any new changes that were created as
+part of the rebase. To achieve this, rebase will save the state of all changes
+in refs/metas prior to running rebase and will restore the entire namespace
+after rebase completes (deleting any newly-created changes). Newly-created
+metacommits are left in place, but will have no effect until garbage collected
+since metacommits are only used if they are reachable from refs/metas.
+
+Change
+------
+The “change” command can be used to list, rename, reset or delete change. It has
+a number of subcommands.
+
+The "list" subcommand lists all local changes that aren’t present in the given
+branch. If the branch name is omitted, all local changes are listed. If given
+the -r argument, it lists remote changes.
+
+The "rename" subcommand renames a change, given its old and new name. If the old
+name is omitted and there is exactly one change pointing to the current HEAD,
+that change is renamed. If there are no changes pointing to the current HEAD,
+one is created with the given name.
+
+The "remove" subcommand deletes a change. This is one way to resolve divergence.
+
+The "new" subcommand creates a new change with the given name and start commit.
+If the name is omitted, it uses the default algorithm for assigning change
+names. If the start commit is omitted, HEAD is used. The start commit may be
+a metacommit, in which case the new change points to that position in the commit
+history. If given the optional --force argument, it will overwrite any existing
+change of the same name. This latter form of "new" can be used to effectively
+reset changes.
+
+If the "new" command points to a normal commit (and not a metacommit), it can
+accept any number of --origin and --replace arguments. If any are present, the
+resulting change branch will point to a metacommit containing the given origin
+and replacement edges.
+
+The "replace" command records a replacement in the obsolescence graph, given a
+list of obsolete commits or metacommits followed by their replacement. This
+behaves like a normal "modify" command, except that the replacement is an
+existing commit. If an obsolete commit points to a metacommit, only a change
+branch pointing to exactly that metacommit moves forward. If an obsolete commit
+points to a normal commit, all change branches pointing to that commit move
+forward. If no change branches moved forward, a new change branch is created
+using the default name.
+
+The "snip" command deletes a commit using obsolescence markers. It marks the
+commit as being obsolete and having been replaced by its parent. If given no
+arguments, it applies to the current commit.
+
+The "prune" command deletes all obsolete changes and all changes that are
+present in the given branch. Note that such changes can be recovered from the
+reflog.
+
+Combined with the GC protection that is offered, this is intended to facilitate
+a workflow that relies on changes instead of branches. Users could choose to
+work with no local branches and use changes instead - both for mailing list and
+gerrit workflows.
+
+Log
+---
+When a commit is shown in git log that is part of a change, it is decorated with
+extra change information. If it is the head of a change, the name of the change
+is shown next to the list of branches. If it is obsolete, it is decorated with
+the text “obsolete, <n> commits behind <changename>”.
+
+Log gets a new --obslog argument indicating that the obsolescence graph should
+be followed instead of the commit graph. This also changes the default
+formatting options to make them more appropriate for viewing different
+iterations of the same commit.
+
+Pull
+----
+
+Pull gets an --evolve argument that will automatically attempt to run "evolve"
+on any affected branches after pulling.
+
+We also introduce an "evolve" enum value for the branch.<name>.rebase config
+value. When set, the evolve behavior will happen automatically for that branch
+after every pull even if the --evolve argument is not used.
+
+Next
+----
+
+The "next" command will reset HEAD to a non-obsolete commit that refers to this
+change as its parent. If there is more than one such change, the user will be
+prompted. If given the --evolve argument, the next commit will be evolved if
+necessary first.
+
+The "next" command can be thought of as the opposite of
+"git reset --hard HEAD^" in that it navigates to a child commit rather than a
+parent.
+
+Other options considered
+========================
+We considered several other options for storing the obsolescence graph. This
+section describes the other options and why they were rejected.
+
+Commit header
+-------------
+Add an “obsoletes” field to the commit header that points backwards from a
+commit to the previous commits it obsoletes.
+
+Pros:
+- Very simple
+- Easy to traverse from a commit to the previous commits it obsoletes.
+Cons:
+- Adds a cost to the storage format, even for commits where the change history
+  is uninteresting.
+- Unconditionally prevents the change history from being garbage collected.
+- Always causes the change history to be shared when pushing or pulling changes.
+
+Git notes
+---------
+Instead of storing obsolescence information in metacommits, the metacommit
+content could go in a new notes namespace - say refs/notes/metacommit. Each note
+would contain the list of obsolete and origin parents, and an automerger could
+be supplied to make it easy to merge the metacommit notes from different remotes.
+
+Pros:
+- Easy to locate all commits obsoleted by a given commit (since there would only
+  be one metacommit for any given commit).
+Cons:
+- Wrong GC behavior (obsolete commits wouldn’t automatically be retained by GC)
+  unless we introduced a special case for these kinds of notes.
+- No way to selectively share or pull the metacommits for one specific change.
+  It would be all-or-nothing, which would be expensive. This could be addressed
+  by changes to the protocol, but this would be invasive.
+- Requires custom auto-merging behavior on fetch.
+
+Tags
+----
+Put the content of the metacommit in a message attached to tag on the
+replacement commit. This is very similar to the git notes approach and has the
+same pros and cons.
+
+Simple forward references
+-------------------------
+Record an edge from an obsolete commit to its replacement in this form:
+
+refs/obsoletes/<A>
+
+pointing to commit <B> as an indication that B is the replacement for the
+obsolete commit A.
+
+Pros:
+- Protects <B> from being garbage collected.
+- Fast lookup for the evolve operation, without additional search structures
+  (“what is the replacement for <A>?” is very fast).
+
+Cons:
+- Can’t represent divergence (which is a P0 requirement).
+- Creates lots of refs (which can be inefficient)
+- Doesn’t provide a way to fetch only refs for a specific change.
+- The obslog command requires a search of all refs.
+
+Complex forward references
+--------------------------
+Record an edge from an obsolete commit to its replacement in this form:
+
+refs/obsoletes/<change_id>/obs<A>_<B>
+
+Pointing to commit <B> as an indication that B is the replacement for obsolete
+commit A.
+
+Pros:
+- Permits sharing and fetching refs for only a specific change.
+- Supports divergence
+- Protects <B> from being garbage collected.
+
+Cons:
+- Creates lots of refs, which is inefficient.
+- Doesn’t provide a good lookup structure for lookups in either direction.
+
+Backward references
+-------------------
+Record an edge from a replacement commit to the obsolete one in this form:
+
+refs/obsolescences/<B>
+
+Cons:
+- Doesn’t provide a way to resolve divergence (which is a P0 requirement).
+- Doesn’t protect <B> from being garbage collected (which could be fixed by
+  combining this with a refs/metas namespace, as in the metacommit variant).
+
+Obsolescences file
+------------------
+Create a custom file (or files) in .git recording obsolescences.
+
+Pros:
+- Can store exactly the information we want with exactly the performance we want
+  for all operations. For example, there could be a disk-based hashtable
+  permitting constant time lookups in either direction.
+
+Cons:
+- Handling GC, pushing, and pulling would all require custom solutions. GC
+  issues could be addressed with a repository format extension.
+
+Squash points
+-------------
+We create and update change branches in refs/metas them at the same time we
+would in the metacommit proposal. However, rather than pointing to a metacommit
+branch they point to normal commits and are treated as “squash points” - markers
+for sequences of commits intended to be squashed together on submission.
+
+Amends and rebases work differently than they do now. Rather than actually
+containing the desired state of a commit, they contain a delta from the previous
+version along with a squash point indicating that the preceding changes are
+intended to be squashed on submission. Specifically, amends would become new
+changes and rebases would become merge commits with the old commit and new
+parent as parents.
+
+When the changes are finally submitted, the squashes are executed, producing the
+final version of the commit.
+
+In addition to the squash points, git would maintain a set of “nosquash” tags
+for commits that were used as ancestors of a change that are not meant to be
+included in the squash.
+
+For example, if we have this commit graph:
+
+A(...)
+B(parent=A)
+C(parent=B)
+
+...and we amend B to produce D, we’d get:
+
+A(...)
+B(parent=A)
+C(parent=B)
+D(parent=B)
+
+...along with a new change branch indicating D should be squashed with its
+parents when submitted:
+
+metas/changeB = D
+metas/changeC = C
+
+We’d also create a nosquash tag for A indicating that A shouldn’t be included
+when changeB is squashed.
+
+If a user amends the change again, they’d get:
+
+A(...)
+B(parent=A)
+C(parent=B)
+D(parent=B)
+E(parent=D)
+
+metas/changeB = E
+metas/changeC = C
+
+Pros:
+- Good GC behavior.
+- Provides a natural way to share changes (they’re just normal branches).
+- Merge-base works automatically without special cases.
+- Rewriting the obslog would be easy using existing git commands.
+- No new data types needed.
+Cons:
+- No way to connect the squashed version of a change to the original, so no way
+  to automatically clean up old changes. This also means users lose all benefits
+  of the evolve command if they prematurely squash their commits. This may occur
+  if a user thinks a change is ready for submission, squashes it, and then later
+  discovers an additional change to make.
+- Histories would look very cluttered (users would see all previous edits to
+  their commit in the commit log, and all previous rebases would show up as
+  merges). Could be quite hard for users to tell what is going on. (Possible
+  fix: also implement a new smart log feature that displays the log as though
+  the squashes had occurred).
+- Need to change the current behavior of current commands (like amend and
+  rebase) in ways that will be unexpected to many users.
-- 
2.20.0.rc1.387.gf8505762e3-goog


^ permalink raw reply related

* Parsing a git HTTP protocol response
From: Farhan Khan @ 2018-12-01  1:05 UTC (permalink / raw)
  To: git

Hi all,

I am writing an implementation of the git HTTP pack protocol in C. It
just does a request to clone a repository. It works pretty well for
small repositories, but seems to fail on larger repositories and I do
not understand why.

All that my code does is send a hard-coded "want" request. As I
understand it, responses come with a four-byte size prefix, then the
data of the size - 4. The first four bytes are the size of the object
in ASCII and after that size, a new object should begin by specifying
its size. The final "0000" string should signify the end.

On small repositories my code works fine. But when use a large git
repository, I hit an object size that cannot be interpreted by ASCII
into a number. In particular, right before the crash I am pretty
consistently getting a size starting with 0x32,0x00 or 0x32,0x30,0x00
(note, it starts with 0x32 and has 0x00 in there). This is not a
readable four byte ascii value, likely an erroneous size value, which
causes the next object size calculation to land incorrectly and
subsequently the program to malfunction.

My questions:
1. Am I misunderstanding the protocol?
2. Does 0x32 signify something?
3. Also, where can I see in the source code git parses the data it
receives from a "want" request?

If you would like to see my code, it is located here:
http://git.farhan.codes/farhan/post
To compile to Linux run: gcc post.c main.c -lcurl -o post
To compile on FreeBSD you can use the Makefile or: cc -L
/usr/local/lib -I /usr/local/include -lcurl main.c post.c -o post
In both cases you need to have libcurl installed.

To run do: ./post [a git http url] [a commit value]
ie: ./post http://git.farhan.codes/farhan/openbsd
373dd5ba116d42cddf1fdcb58b578a4274f6d589

I have a lot of debugging printf() messages, but it eventually hits a
point where you see this:

========Start=========
Current stats: Current state: 999 Received: 1448
We have enough bytes, moving forward
== New Object
No Error, object is 32 bytes
Size bytes: 32 30 00 00

The program interprets the size of {0x32,0x30,0x00,0x00} to be "20"
which in decimal is 32, causing the next read to fail.
This problem repeats on a few different repositories.

Any assistance is welcome, I am very stuck on how the HTTP git protocol works.
Thanks,
--
Farhan Khan
PGP Fingerprint: B28D 2726 E2BC A97E 3854 5ABE 9A9F 00BC D525 16EE

^ permalink raw reply

* Re: [RFC 2/2] exclude-promisor-objects: declare when option is allowed
From: Matthew DeVore @ 2018-12-01  1:32 UTC (permalink / raw)
  To: Jeff King, Matthew DeVore; +Cc: git, gitster, pclouds, jonathantanmy, jeffhost
In-Reply-To: <20181121164019.GA24621@sigill.intra.peff.net>



On 11/21/2018 08:40 AM, Jeff King wrote:
> On Mon, Oct 22, 2018 at 06:13:42PM -0700, Matthew DeVore wrote:
> 
>> diff --git a/builtin/prune.c b/builtin/prune.c
>> index 41230f8215..11284d0bf3 100644
>> --- a/builtin/prune.c
>> +++ b/builtin/prune.c
>> @@ -120,6 +120,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
>>   	save_commit_buffer = 0;
>>   	read_replace_refs = 0;
>>   	ref_paranoia = 1;
>> +	revs.allow_exclude_promisor_objects_opt = 1;
>>   	repo_init_revisions(the_repository, &revs, prefix);
>>   
>>   	argc = parse_options(argc, argv, prefix, options, prune_usage, 0);
> 
> I think this line is in the wrong place. The very first thing
> repo_init_revisions() will do is memset() the revs struct to all-zeroes,
> so it cannot possibly be doing anything.

Ah of course :)

> 
> Normally it would need to go after init_revisions() but before
> setup_revisions(), but we don't seem to call the latter at all in
> builtin/prune.c. Which makes sense, because you cannot pass options to
> influence the reachability traversal. So I don't think we need to care
> about this flag at all here.
Agreed, prune.c doesn't use setup_revisions() even transitively, so we 
don't care about this flag.

> 
> Speaking of which, would this flag work better as a field in
> setup_revision_opt, which is passed to setup_revisions()? The intent
> seem to be to influence how we parse command-line arguments, and that's
> where other similar flags are (e.g., assume_dashdash).

Good idea. This would solve the problem of mistakenly believing the flag 
matters when it doesn't, since it is in the struct which is used as the 
arguments of the exact function that cares about it. Here's a new patch 
- I'm tweaking e-mail client settings so hopefully this makes it to the 
list without mangling - if not I'll resend it with `git-send-email` later.

 From 941c89fe1e226ed4d210ce35d0d906526b8277ed Mon Sep 17 00:00:00 2001
From: Matthew DeVore <matvore@google.com>
Date: Fri, 30 Nov 2018 16:43:32 -0800
Subject: [PATCH] revisions.c: put promisor option in specialized struct

Put the allow_exclude_promisor_objects flag in setup_revision_opt. When
it was in rev_info, it was unclear when it was used, since rev_info is
passed to functions that don't use the flag. This resulted in
unnecessary setting of the flag in prune.c, so fix that as well.

Signed-off-by: Matthew DeVore <matvore@google.com>
---
  builtin/pack-objects.c |  7 +++++--
  builtin/prune.c        |  1 -
  builtin/rev-list.c     |  6 ++++--
  revision.c             | 17 ++++++++++++-----
  revision.h             |  4 ++--
  5 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 24bba8147f..b22c99f540 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -3084,14 +3084,17 @@ static void record_recent_commit(struct commit 
*commit, void *data)
  static void get_object_list(int ac, const char **av)
  {
  	struct rev_info revs;
+	struct setup_revision_opt s_r_opt;
  	char line[1000];
  	int flags = 0;
  	int save_warning;

  	repo_init_revisions(the_repository, &revs, NULL);
  	save_commit_buffer = 0;
-	revs.allow_exclude_promisor_objects_opt = 1;
-	setup_revisions(ac, av, &revs, NULL);
+
+	memset(&s_r_opt, 0, sizeof(s_r_opt));
+	s_r_opt.allow_exclude_promisor_objects = 1;
+	setup_revisions(ac, av, &revs, &s_r_opt);

  	/* make sure shallows are read */
  	is_repository_shallow(the_repository);
diff --git a/builtin/prune.c b/builtin/prune.c
index e42653b99c..1ec9ddd751 100644
--- a/builtin/prune.c
+++ b/builtin/prune.c
@@ -120,7 +120,6 @@ int cmd_prune(int argc, const char **argv, const 
char *prefix)
  	save_commit_buffer = 0;
  	read_replace_refs = 0;
  	ref_paranoia = 1;
-	revs.allow_exclude_promisor_objects_opt = 1;
  	repo_init_revisions(the_repository, &revs, prefix);

  	argc = parse_options(argc, argv, prefix, options, prune_usage, 0);
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index 3a2c0c23b6..c3095c6fed 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -362,6 +362,7 @@ int cmd_rev_list(int argc, const char **argv, const 
char *prefix)
  {
  	struct rev_info revs;
  	struct rev_list_info info;
+	struct setup_revision_opt s_r_opt;
  	int i;
  	int bisect_list = 0;
  	int bisect_show_vars = 0;
@@ -375,7 +376,6 @@ int cmd_rev_list(int argc, const char **argv, const 
char *prefix)
  	git_config(git_default_config, NULL);
  	repo_init_revisions(the_repository, &revs, prefix);
  	revs.abbrev = DEFAULT_ABBREV;
-	revs.allow_exclude_promisor_objects_opt = 1;
  	revs.commit_format = CMIT_FMT_UNSPECIFIED;
  	revs.do_not_die_on_missing_tree = 1;

@@ -407,7 +407,9 @@ int cmd_rev_list(int argc, const char **argv, const 
char *prefix)
  		}
  	}

-	argc = setup_revisions(argc, argv, &revs, NULL);
+	memset(&s_r_opt, 0, sizeof(s_r_opt));
+	s_r_opt.allow_exclude_promisor_objects = 1;
+	argc = setup_revisions(argc, argv, &revs, &s_r_opt);

  	memset(&info, 0, sizeof(info));
  	info.revs = &revs;
diff --git a/revision.c b/revision.c
index 13e0519c02..221ba79594 100644
--- a/revision.c
+++ b/revision.c
@@ -1791,7 +1791,8 @@ static void add_message_grep(struct rev_info 
*revs, const char *pattern)
  }

  static int handle_revision_opt(struct rev_info *revs, int argc, const 
char **argv,
-			       int *unkc, const char **unkv)
+			       int *unkc, const char **unkv,
+			       int allow_exclude_promisor_objects)
  {
  	const char *arg = argv[0];
  	const char *optarg;
@@ -2151,7 +2152,7 @@ static int handle_revision_opt(struct rev_info 
*revs, int argc, const char **arg
  		revs->limited = 1;
  	} else if (!strcmp(arg, "--ignore-missing")) {
  		revs->ignore_missing = 1;
-	} else if (revs->allow_exclude_promisor_objects_opt &&
+	} else if (allow_exclude_promisor_objects &&
  		   !strcmp(arg, "--exclude-promisor-objects")) {
  		if (fetch_if_missing)
  			BUG("exclude_promisor_objects can only be used when 
fetch_if_missing is 0");
@@ -2173,7 +2174,8 @@ void parse_revision_opt(struct rev_info *revs, 
struct parse_opt_ctx_t *ctx,
  			const char * const usagestr[])
  {
  	int n = handle_revision_opt(revs, ctx->argc, ctx->argv,
-				    &ctx->cpidx, ctx->out);
+				    &ctx->cpidx, ctx->out,
+				    /*allow_exclude_promisor_objects=*/0);
  	if (n <= 0) {
  		error("unknown option `%s'", ctx->argv[0]);
  		usage_with_options(usagestr, options);
@@ -2340,9 +2342,12 @@ int setup_revisions(int argc, const char **argv, 
struct rev_info *revs, struct s
  	int i, flags, left, seen_dashdash, got_rev_arg = 0, revarg_opt;
  	struct argv_array prune_data = ARGV_ARRAY_INIT;
  	const char *submodule = NULL;
+	int allow_exclude_prom_objs = 0;

-	if (opt)
+	if (opt) {
  		submodule = opt->submodule;
+		allow_exclude_prom_objs = opt->allow_exclude_promisor_objects;
+	}

  	/* First, search for "--" */
  	if (opt && opt->assume_dashdash) {
@@ -2391,7 +2396,9 @@ int setup_revisions(int argc, const char **argv, 
struct rev_info *revs, struct s
  				continue;
  			}

-			opts = handle_revision_opt(revs, argc - i, argv + i, &left, argv);
+			opts = handle_revision_opt(revs, argc - i, argv + i,
+						   &left, argv,
+						   allow_exclude_prom_objs);
  			if (opts > 0) {
  				i += opts - 1;
  				continue;
diff --git a/revision.h b/revision.h
index 7987bfcd2e..7d6e050569 100644
--- a/revision.h
+++ b/revision.h
@@ -161,7 +161,6 @@ struct rev_info {
  			do_not_die_on_missing_tree:1,

  			/* for internal use only */
-			allow_exclude_promisor_objects_opt:1,
  			exclude_promisor_objects:1;

  	/* Diff flags */
@@ -297,7 +296,8 @@ struct setup_revision_opt {
  	const char *def;
  	void (*tweak)(struct rev_info *, struct setup_revision_opt *);
  	const char *submodule;	/* TODO: drop this and use rev_info->repo */
-	int assume_dashdash;
+	int assume_dashdash : 1;
+	int allow_exclude_promisor_objects : 1;
  	unsigned revarg_opt;
  };

-- 
2.20.0.rc1.387.gf8505762e3-goog

^ permalink raw reply related

* [PATCH] t6036: avoid "cp -a"
From: Carlo Marcelo Arenas Belón @ 2018-12-01  2:52 UTC (permalink / raw)
  To: git; +Cc: newren

b8cd1bb713 ("t6036, t6043: increase code coverage for file collision handling", 2018-11-07) uses this GNU extension that is not available in a POSIX complaint
cp; use cp -R instead

Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
---
to be applied on top of en/merge-path-collision for next

 t/t6036-recursive-corner-cases.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh
index b7488b00c0..fdb120d0dc 100755
--- a/t/t6036-recursive-corner-cases.sh
+++ b/t/t6036-recursive-corner-cases.sh
@@ -1631,7 +1631,7 @@ test_expect_success 'check nested conflicts' '
 
 		# Compare m to expected contents
 		>empty &&
-		cp -a m_stage_2 expected_final_m &&
+		cp -R m_stage_2 expected_final_m &&
 		test_must_fail git merge-file --diff3 \
 			-L "HEAD"                     \
 			-L "merged common ancestors"  \
-- 
2.20.0.rc1.6.ga1598010f


^ permalink raw reply related

* Re: Parsing a git HTTP protocol response
From: Bryan Turner @ 2018-12-01  2:58 UTC (permalink / raw)
  To: khanzf; +Cc: Git Users
In-Reply-To: <CAFd4kYAzOd8qwEDgVf-W+1S3NoZFUa_vZsUfuNNjL_XsuesO5w@mail.gmail.com>

On Fri, Nov 30, 2018 at 5:05 PM Farhan Khan <khanzf@gmail.com> wrote:
>
> Hi all,
>
> I am writing an implementation of the git HTTP pack protocol in C. It
> just does a request to clone a repository. It works pretty well for
> small repositories, but seems to fail on larger repositories and I do
> not understand why.
>
> All that my code does is send a hard-coded "want" request. As I
> understand it, responses come with a four-byte size prefix, then the
> data of the size - 4. The first four bytes are the size of the object
> in ASCII and after that size, a new object should begin by specifying
> its size. The final "0000" string should signify the end.
>
> On small repositories my code works fine. But when use a large git
> repository, I hit an object size that cannot be interpreted by ASCII
> into a number. In particular, right before the crash I am pretty
> consistently getting a size starting with 0x32,0x00 or 0x32,0x30,0x00
> (note, it starts with 0x32 and has 0x00 in there). This is not a
> readable four byte ascii value, likely an erroneous size value, which
> causes the next object size calculation to land incorrectly and
> subsequently the program to malfunction.
>
> My questions:
> 1. Am I misunderstanding the protocol?
> 2. Does 0x32 signify something?
> 3. Also, where can I see in the source code git parses the data it
> receives from a "want" request?
>
> If you would like to see my code, it is located here:
> http://git.farhan.codes/farhan/post
> To compile to Linux run: gcc post.c main.c -lcurl -o post
> To compile on FreeBSD you can use the Makefile or: cc -L
> /usr/local/lib -I /usr/local/include -lcurl main.c post.c -o post
> In both cases you need to have libcurl installed.
>
> To run do: ./post [a git http url] [a commit value]
> ie: ./post http://git.farhan.codes/farhan/openbsd
> 373dd5ba116d42cddf1fdcb58b578a4274f6d589
>
> I have a lot of debugging printf() messages, but it eventually hits a
> point where you see this:
>
> ========Start=========
> Current stats: Current state: 999 Received: 1448
> We have enough bytes, moving forward
> == New Object
> No Error, object is 32 bytes
> Size bytes: 32 30 00 00

I modified your debugging output a little bit, and right before the
failure happens I see this in my output:

========Start=========
Current stats: Current state: 999 Received: 1298
Read complete; still missing 1296 bytes (6901 read of 8197)
Offset: 1298

========Start=========
Current stats: Current state: 999 Received: 1298
Read complete; 2 more bytes in buffer
== New Object
Size bytes: 32 30 00 2b

Based on that, it appears what's happening is you're not handling the
case where you end up with fewer than 4 bytes in the buffer. As a
result, memcpy reads past the end of the response buffer and gets
whatever it gets, resulting in an incorrect parsed size.

The while loop in pack_protocol_line is checking +1, but I think it
should be checking +3 to ensure there's at least 4 bytes so it can get
a complete size. The "parseread" struct will need to grow a couple
more fields to allow buffering some additional bytes between
pack_protocol_line calls (because curl requires the write function to
always consume the full buffer) and, at the start of the loop, when
reading/parsing a size, the code will need to consider any buffered
bytes from the previous function call. That requires some knock-on
changes to how the offset is handled, as well as the the initial
"psize" set when starting a new packet.

Once you start accounting for reads that cut off in 1, 2 or 3 bytes
into the 4 required to parse a size, your program should be able to
run to completion.

Here's a (very ugly) patch I threw together on top of your code:

diff --git a/main.c b/main.c
index 956362b..8873fd5 100644
--- a/main.c
+++ b/main.c
@@ -71,7 +71,7 @@ int main(int argc, char *argv[]) {
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
  curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)content_length);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, &parseread);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, pack_protocol_line);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &pack_protocol_line);

  res = curl_easy_perform(curl);
  if (curl != CURLE_OK)
diff --git a/post.c b/post.c
index cfffd5c..4f8512c 100644
--- a/post.c
+++ b/post.c
@@ -36,89 +36,83 @@ size_t pack_protocol_line(void *buffer, size_t
size, size_t nmemb, void *userp)
 {
  unsigned char *reply = buffer;
  struct parseread *parseread = userp;
- int offset = 0;
+ int offset = 0, pending = 0, remaining = 0;
  char tmp[5];
- int check;
-
- int pool = size * nmemb;

  printf("\n\n========Start=========\n");
- printf("Current stats: Current state: %d Received: %ld\n",
parseread->state, size*nmemb);
+ printf("Current stats: Current state: %d Received: %ld\n",
parseread->state, nmemb);

- while(offset + 1 < size + nmemb) {
+ while (offset + 3 < nmemb) {
  if (parseread->state == STATE_NEWLINE) {
  printf("== New Object\n");
  bzero(tmp, 5);
- memcpy(tmp, buffer+offset, 4); tmp[4] = '\0';
- check = sscanf(tmp, "%04x", &parseread->osize);

- if (parseread->osize == 0) {
- printf("Only happens if reached terminating 0000\n");
+ if (parseread->bsize > 0) {
+ // If there are buffered size bytes, consume them
+ memcpy(tmp, parseread->buffer, parseread->bsize);
+ memcpy(tmp + parseread->bsize, buffer + offset, 4 - parseread->bsize);
+ offset += 4 - parseread->bsize;
+ parseread->bsize = 0;
+ } else {
+ memcpy(tmp, buffer+offset, 4);
  offset += 4;
- break;
  }
+ tmp[4] = '\0';

- if (check == 0) {
- printf("Error, unable to parse object size\n");
- printf("Size bytes: %02x %02x %02x %02x\n",
- reply[offset+0],
- reply[offset+1],
- reply[offset+2],
- reply[offset+3]);
- printf("Data: %02x %02x %02x %02x\n",
- reply[offset+4],
- reply[offset+5],
- reply[offset+6],
- reply[offset+7]);
- exit(-1);
- }
- else {
- printf("No Error, object is %d bytes\n", parseread->osize);
- printf("Size bytes: %02x %02x %02x %02x\n",
- reply[offset+0],
- reply[offset+1],
- reply[offset+2],
- reply[offset+3]);
- printf("%02x %02x %02x %02x\n",
- reply[offset+4],
- reply[offset+5],
- reply[offset+6],
- reply[offset+7]);
+ printf("Size bytes: %02x %02x %02x %02x\n", tmp[0], tmp[1], tmp[2], tmp[3]);
+ parseread->osize = (int) strtol(tmp, NULL, 16);
+ printf("Parsed size: %d\n", parseread->osize);
+
+ if (parseread->osize == 0) {
+ printf("Only happens if reached terminating 0000\n");
+ break;
  }

- printf("Size: %d\n", parseread->osize);
- parseread->psize = 0;
+ parseread->psize = 4;

  // This classifies the object
- if ( strncmp(reply+offset+4, "NAK\n", 4)==0)
+ if ( strncmp(reply+offset, "NAK\n", 4)==0)
  parseread->state = STATE_NAK;
- else if (reply[offset+4] == 0x02)
+ else if (reply[offset] == 0x02)
  parseread->state = STATE_REMOTE;
  else
  parseread->state = STATE_UNKNOWN;
  }

- if ( (pool - offset) > (parseread->osize - parseread->psize) ) {
- printf("We have enough bytes, moving forward\n");
+ pending = parseread->osize - parseread->psize;
+ remaining = nmemb - offset;
+
+ if ( remaining > pending ) {
+ printf("Read complete; %d more bytes in buffer\n", remaining - pending);
  process_objects(reply+offset, parseread);
  offset += (parseread->osize - parseread->psize);
  parseread->state = STATE_NEWLINE;
  }
- else if ( (pool - offset) ==(parseread->osize - parseread->psize) ) {
- printf("They are the same length\n");
+ else if ( remaining == pending ) {
+ printf("Read complete; buffer exhausted\n");
  process_objects(reply+offset, parseread);
  offset += (parseread->osize - parseread->psize);
  parseread->state = STATE_NEWLINE;
  }
- else if ( (pool - offset) < (parseread->osize - parseread->psize)) {
- printf("We do not have enough bytes\n");
+ else if ( remaining < pending ) {
+ printf("Read complete; still missing %d bytes (%d read of %d)\n",
+ pending - remaining, parseread->psize + remaining, parseread->osize);
  process_objects(reply+offset, parseread);
- parseread->psize += (pool - offset);
- offset = pool;
+ parseread->psize += remaining;
+ offset = nmemb;
  }
  }

  printf("Offset: %d\n", offset);
+ if (offset < nmemb) {
+ // We don't have enough bytes to read the next size, so buffer it
+ printf("Short read; %d bytes left", nmemb - offset);
+ bzero(parseread->buffer, 4);
+ parseread->bsize = nmemb - offset;
+ memcpy(parseread->buffer, buffer+offset, parseread->bsize);
+
+ offset = nmemb;
+ }

  return offset;
 }
diff --git a/post.h b/post.h
index a229342..01a2669 100644
--- a/post.h
+++ b/post.h
@@ -5,6 +5,8 @@ struct parseread {
  int state; // current state
  int osize; // object size
  int psize; // processed size
+ char buffer[4];
+ int bsize;
 };

 #define STATE_NEWLINE 0

Again, it's not pretty, but with those changes a `./post` on your
openbsd URL succeeds.

========Start=========
Current stats: Current state: 999 Received: 503
Read complete; 77 more bytes in buffer
== New Object
Size bytes: 30 30 30 36
Parsed size: 6
Read complete; 71 more bytes in buffer
== New Object
Size bytes: 30 30 34 33
Parsed size: 67
Read complete; 4 more bytes in buffer
Remote: l 1798261 (delta 1438982), reused 1795494 (delta 1436215)
0000
== New Object
Size bytes: 30 30 30 30
Parsed size: 0
Only happens if reached terminating 0000
Offset: 503
curl_easy_perform() failed: No error

Bryan

^ permalink raw reply related

* Re: Parsing a git HTTP protocol response
From: Bryan Turner @ 2018-12-01  2:59 UTC (permalink / raw)
  To: khanzf; +Cc: Git Users
In-Reply-To: <CAGyf7-Eq6tQQocjXFzngX=vo3FWba=tvmAqGybcLxLXn6ZZkpA@mail.gmail.com>

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

On Fri, Nov 30, 2018 at 6:58 PM Bryan Turner <bturner@atlassian.com> wrote:
>
> Here's a (very ugly) patch I threw together on top of your code:
...snip

Gmail butchered my patch, so here it is as an attachment.

Bryan

[-- Attachment #2: short-size-reads.patch --]
[-- Type: application/octet-stream, Size: 5234 bytes --]

diff --git a/main.c b/main.c
index 956362b..8873fd5 100644
--- a/main.c
+++ b/main.c
@@ -71,7 +71,7 @@ int main(int argc, char *argv[]) {
 		curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
 		curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)content_length);
 		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &parseread);
-		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, pack_protocol_line);
+		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &pack_protocol_line);
 
 		res = curl_easy_perform(curl);
 		if (curl != CURLE_OK)
diff --git a/post.c b/post.c
index cfffd5c..4f8512c 100644
--- a/post.c
+++ b/post.c
@@ -36,89 +36,83 @@ size_t pack_protocol_line(void *buffer, size_t size, size_t nmemb, void *userp)
 {
 	unsigned char *reply = buffer;
 	struct parseread *parseread = userp;
-	int offset = 0;
+	int offset = 0, pending = 0, remaining = 0;
 	char tmp[5];
-	int check;
-
-	int pool = size * nmemb;
 
 	printf("\n\n========Start=========\n");
-	printf("Current stats: Current state: %d Received: %ld\n", parseread->state, size*nmemb);
+	printf("Current stats: Current state: %d Received: %ld\n", parseread->state, nmemb);
 
-	while(offset + 1 < size + nmemb) {
+	while (offset + 3 < nmemb) {
 		if (parseread->state == STATE_NEWLINE) { 
 			printf("== New Object\n");
 			bzero(tmp, 5);
-			memcpy(tmp, buffer+offset, 4); tmp[4] = '\0';
-			check = sscanf(tmp, "%04x", &parseread->osize);
 
-			if (parseread->osize == 0) {
-				printf("Only happens if reached terminating 0000\n");
+			if (parseread->bsize > 0) {
+				// If there are buffered size bytes, consume them
+				memcpy(tmp, parseread->buffer, parseread->bsize);
+				memcpy(tmp + parseread->bsize, buffer + offset, 4 - parseread->bsize);
+				offset += 4 - parseread->bsize;
+				parseread->bsize = 0;
+			} else {
+				memcpy(tmp, buffer+offset, 4);
 				offset += 4;
-				break;
 			}
+			tmp[4] = '\0';
 
-			if (check == 0) {
-				printf("Error, unable to parse object size\n");
-				printf("Size bytes: %02x %02x %02x %02x\n",
-					reply[offset+0],
-					reply[offset+1],
-					reply[offset+2],
-					reply[offset+3]);
-				printf("Data: %02x %02x %02x %02x\n",
-					reply[offset+4],
-					reply[offset+5],
-					reply[offset+6],
-					reply[offset+7]);
-				exit(-1);
-			}
-			else {
-				printf("No Error, object is %d bytes\n", parseread->osize);
-				printf("Size bytes: %02x %02x %02x %02x\n",
-					reply[offset+0],
-					reply[offset+1],
-					reply[offset+2],
-					reply[offset+3]);
-				printf("%02x %02x %02x %02x\n",
-					reply[offset+4],
-					reply[offset+5],
-					reply[offset+6],
-					reply[offset+7]);
+			printf("Size bytes: %02x %02x %02x %02x\n", tmp[0], tmp[1], tmp[2], tmp[3]);
+			parseread->osize = (int) strtol(tmp, NULL, 16);
+			printf("Parsed size: %d\n", parseread->osize);
+
+			if (parseread->osize == 0) {
+				printf("Only happens if reached terminating 0000\n");
+				break;
 			}
 
-			printf("Size: %d\n", parseread->osize);
-			parseread->psize = 0;
+			parseread->psize = 4;
 
 			// This classifies the object
-			if ( strncmp(reply+offset+4, "NAK\n", 4)==0)
+			if ( strncmp(reply+offset, "NAK\n", 4)==0)
 				parseread->state = STATE_NAK;
-			else if (reply[offset+4] == 0x02)
+			else if (reply[offset] == 0x02)
 				parseread->state = STATE_REMOTE;
 			else
 				parseread->state = STATE_UNKNOWN;
 		}
 
-		if ( (pool - offset) > (parseread->osize - parseread->psize) ) {
-			printf("We have enough bytes, moving forward\n");
+		pending = parseread->osize - parseread->psize;
+		remaining = nmemb - offset;
+
+		if ( remaining > pending ) {
+			printf("Read complete; %d more bytes in buffer\n", remaining - pending);
 			process_objects(reply+offset, parseread);
 			offset += (parseread->osize - parseread->psize); 
 			parseread->state = STATE_NEWLINE;
 		}
-		else if ( (pool - offset) ==(parseread->osize - parseread->psize) ) {
-			printf("They are the same length\n");
+		else if ( remaining == pending ) {
+			printf("Read complete; buffer exhausted\n");
 			process_objects(reply+offset, parseread);
 			offset += (parseread->osize - parseread->psize);
 			parseread->state = STATE_NEWLINE;
 		}
-		else if ( (pool - offset) < (parseread->osize - parseread->psize)) {
-			printf("We do not have enough bytes\n");
+		else if ( remaining < pending ) {
+			printf("Read complete; still missing %d bytes (%d read of %d)\n",
+					pending - remaining, parseread->psize + remaining, parseread->osize);
 			process_objects(reply+offset, parseread);
-			parseread->psize += (pool - offset);
-			offset = pool;
+			parseread->psize += remaining;
+			offset = nmemb;
 		}
 	}
 
 	printf("Offset: %d\n", offset);
+	if (offset < nmemb) {
+		// We don't have enough bytes to read the next size, so buffer it
+		printf("Short read; %d bytes left", nmemb - offset);
+		bzero(parseread->buffer, 4);
+		parseread->bsize = nmemb - offset;
+		memcpy(parseread->buffer, buffer+offset, parseread->bsize);
+
+		offset = nmemb;
+	}
 
 	return offset;
 }
diff --git a/post.h b/post.h
index a229342..01a2669 100644
--- a/post.h
+++ b/post.h
@@ -5,6 +5,8 @@ struct parseread {
 	int state; // current state
 	int osize; // object size
 	int psize; // processed size
+	char buffer[4];
+	int bsize;
 };
 
 #define STATE_NEWLINE		0

^ permalink raw reply related

* Re: [PATCH] t6036: avoid "cp -a"
From: Elijah Newren @ 2018-12-01  4:21 UTC (permalink / raw)
  To: carenas; +Cc: Git Mailing List
In-Reply-To: <20181201025212.54244-1-carenas@gmail.com>

Hi,

Thanks for the patch!

On Fri, Nov 30, 2018 at 6:52 PM Carlo Marcelo Arenas Belón
<carenas@gmail.com> wrote:
>
> b8cd1bb713 ("t6036, t6043: increase code coverage for file collision handling", 2018-11-07) uses this GNU extension that is not available in a POSIX complaint

This is an extraordinarily long line; can you rewrap at around 72 characters?

> cp; use cp -R instead
>
> Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
> ---
> to be applied on top of en/merge-path-collision for next
>
>  t/t6036-recursive-corner-cases.sh | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh
> index b7488b00c0..fdb120d0dc 100755
> --- a/t/t6036-recursive-corner-cases.sh
> +++ b/t/t6036-recursive-corner-cases.sh
> @@ -1631,7 +1631,7 @@ test_expect_success 'check nested conflicts' '
>
>                 # Compare m to expected contents
>                 >empty &&
> -               cp -a m_stage_2 expected_final_m &&
> +               cp -R m_stage_2 expected_final_m &&
>                 test_must_fail git merge-file --diff3 \
>                         -L "HEAD"                     \
>                         -L "merged common ancestors"  \
> --
> 2.20.0.rc1.6.ga1598010f

Oops.  Thanks for catching.  To be honest, we don't even need -a, -R,
etc. -- it was just a habit for me to add -a after cp.  A simple cp
would do, though what you have here is fine too.

^ permalink raw reply

* Re: [RFC PATCH] Introduce "precious" file concept
From: Duy Nguyen @ 2018-12-01  6:21 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: Junio C Hamano, per.lundberg, brian m. carlson, Git Mailing List,
	jost, Joshua Jensen, git, Clemens Buchacher,
	Holger Hellmuth (IKS), Kevin Ballard
In-Reply-To: <875zwgzx4v.fsf@evledraar.gmail.com>

On Wed, Nov 28, 2018 at 10:54 PM Ævar Arnfjörð Bjarmason
<avarab@gmail.com> wrote:
> But we must have some viable way to repair warts in the tools, and
> losing user data is a *big* wart.
>
> I don't think something like the endgame you've described in
> https://public-inbox.org/git/xmqqzhtwuhpc.fsf@gitster-ct.c.googlers.com/
> is ever going to work. Novice git users (the vast majority) are not
> going to diligently update both .gitignore and some .gitattribute
> mechanism in lockstep. I'd bet most git users haven't read more than a
> few paragraphs of our entire documentation at best.
>
> So what's the way forward? I think ultimately we must move to something
> where we effectively version the entire CLI UI similar to stable API
> versions. I.e. for things like this that would break some things (or
> Duy's new "split checkout") introduce them as flags first, then bundle
> up all such flags and cut a major release "Git 3, 4, ...", and
> eventually remove old functionality.

Related to Duy's new "split chekckout", I just realized that I added
--overwrite-ignore (enabled by default) [1] years ago to allow to out
out of this behavior. We could turn --no-overwrite-ignore by default
on the new command "git switch-branch" to err on the safe side. Then
the user could switch to --overwrite-ignore once they learn more about
gitignore and gitattributes (or the coming "backup log"). I'm not sure
if I really like this, but at least it's one of the options.

[1] https://public-inbox.org/git/1322388933-6284-2-git-send-email-pclouds@gmail.com/
-- 
Duy

^ permalink raw reply

* [L10N] Kickoff for Git 2.20.0 round 2
From: Jiang Xin @ 2018-12-01  9:34 UTC (permalink / raw)
  To: Alexander Shopov, Jordi Mas, Ralf Thielow, Christopher Díaz,
	Jean-Noël Avila, Marco Paolone, Gwan-gyeong Mun,
	Vasco Almeida, Dimitriy Ryazantcev, Peter Krefting,
	Trần Ngọc Quân, Jiang Xin
  Cc: Git List

Hi,

Two typos are fixed in upstream via commit v2.20.0-rc1-7-gd355e46a15:

    --- a/http.c
    +++ b/http.c
    -           warning(_("CURLSSLOPT_NO_REVOKE not suported with cURL
< 7.44.0"));
    +           warning(_("CURLSSLOPT_NO_REVOKE not supported with
cURL < 7.44.0"));

    --- a/midx.c
    +++ b/midx.c
    -           die(_("bad pack-int-id: %u (%u total packs"),
    +           die(_("bad pack-int-id: %u (%u total packs)"),

For l10n teams that have already submitted for l10n round 1, I made a
batch commit to fix fuzzy translations, see pull request:

    https://github.com/git-l10n/git-po/pull/331

For other l10n teams, please update your translations against the new
pot file from the usual place:

    https://github.com/git-l10n/git-po/

--
Jiang Xin

^ permalink raw reply

* Re: [PATCH] t6036: avoid "cp -a"
From: Junio C Hamano @ 2018-12-01 12:02 UTC (permalink / raw)
  To: Elijah Newren; +Cc: carenas, Git Mailing List
In-Reply-To: <CABPp-BG0=bGW54eMHCiVMbU3dwccZM06qy2gzqm1CE-TUFZ2zg@mail.gmail.com>

Elijah Newren <newren@gmail.com> writes:

> Thanks for the patch!
>
> On Fri, Nov 30, 2018 at 6:52 PM Carlo Marcelo Arenas Belón
> ...
> Oops.  Thanks for catching.  To be honest, we don't even need -a, -R,
> etc. -- it was just a habit for me to add -a after cp.  A simple cp
> would do, though what you have here is fine too.

Thanks, both.  I think the topic won't escape 'next' until 2.20
final, and after that we can rewind 'next', so it may be better
to squash it in, but anyway...

-- >8 --
From: Carlo Marcelo Arenas Belón <carenas@gmail.com>
Date: Fri, 30 Nov 2018 18:52:12 -0800
Subject: [PATCH] t6036: avoid non-portable "cp -a"

b8cd1bb713 ("t6036, t6043: increase code coverage for file collision
handling", 2018-11-07) uses this GNU extension that is not available
in a POSIX complaint cp.  In this particular case, there is no need to
use the option, as it is just copying a single file to create another
file.

Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 t/t6036-recursive-corner-cases.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh
index b7488b00c0..d23b948f27 100755
--- a/t/t6036-recursive-corner-cases.sh
+++ b/t/t6036-recursive-corner-cases.sh
@@ -1631,7 +1631,7 @@ test_expect_success 'check nested conflicts' '
 
 		# Compare m to expected contents
 		>empty &&
-		cp -a m_stage_2 expected_final_m &&
+		cp m_stage_2 expected_final_m &&
 		test_must_fail git merge-file --diff3 \
 			-L "HEAD"                     \
 			-L "merged common ancestors"  \
-- 
2.20.0-rc1-10-g7068cbc4ab


^ permalink raw reply related

* [ANNOUNCE] Git v2.20.0-rc2
From: Junio C Hamano @ 2018-12-01 14:58 UTC (permalink / raw)
  To: git; +Cc: Linux Kernel, git-packagers

A release candidate Git v2.20.0-rc2 is now available for testing
at the usual places.  It is comprised of 934 non-merge commits
since v2.19.0, contributed by 76 people, 25 of which are new faces.

The tarballs are found at:

    https://www.kernel.org/pub/software/scm/git/testing/

The following public repositories all have a copy of the
'v2.20.0-rc2' tag and the 'master' branch that the tag points at:

  url = https://kernel.googlesource.com/pub/scm/git/git
  url = git://repo.or.cz/alt-git.git
  url = https://github.com/gitster/git

New contributors whose contributions weren't in v2.19.0 are as follows.
Welcome to the Git development community!

  Aaron Lindsay, Alexander Pyhalov, Anton Serbulov, Brendan
  Forster, Carlo Marcelo Arenas Belón, Daniels Umanovskis, David
  Zych, Đoàn Trần Công Danh, Frederick Eaton, Greg Hurrell,
  James Knight, Jann Horn, Joshua Watt, Loo Rong Jie, Lucas
  De Marchi, Matthew DeVore, Mihir Mehta, Nickolai Belakovski,
  Roger Strain, Sam McKelvie, Saulius Gurklys, Shulhan, Steven
  Fernandez, Strain, Roger L, and Tim Schumacher.

Returning contributors who helped this release are as follows.
Thanks for your continued support.

  Ævar Arnfjörð Bjarmason, Alban Gruin, Andreas Gruenbacher,
  Andreas Heiduk, Antonio Ospite, Ben Peart, Brandon Williams,
  brian m. carlson, Christian Couder, Christian Hesse, Denton Liu,
  Derrick Stolee, Elijah Newren, Eric Sunshine, Jean-Noël Avila,
  Jeff Hostetler, Jeff King, Johannes Schindelin, Johannes Sixt,
  Jonathan Nieder, Jonathan Tan, Josh Steadmon, Junio C Hamano,
  Karsten Blees, Luke Diamand, Martin Ågren, Max Kirillov,
  Michael Witten, Michał Górny, Nguyễn Thái Ngọc Duy, Noam
  Postavsky, Olga Telezhnaya, Phillip Wood, Pratik Karki, Rafael
  Ascensão, Ralf Thielow, Ramsay Jones, Rasmus Villemoes, René
  Scharfe, Sebastian Staudt, Stefan Beller, Stephen P. Smith, Steve
  Hoelzer, Sven Strickroth, SZEDER Gábor, Tao Qingyun, Taylor
  Blau, Thomas Gummerer, Todd Zullinger, Torsten Bögershausen,
  and Uwe Kleine-König.

----------------------------------------------------------------

Git 2.20 Release Notes (draft)
==============================

Backward Compatibility Notes
----------------------------

 * "git branch -l <foo>" used to be a way to ask a reflog to be
   created while creating a new branch, but that is no longer the
   case.  It is a short-hand for "git branch --list <foo>" now.

 * "git push" into refs/tags/* hierarchy is rejected without getting
   forced, but "git fetch" (misguidedly) used the "fast forwarding"
   rule used for the refs/heads/* hierarchy; this has been corrected,
   which means some fetches of tags that did not fail with older
   version of Git will fail without "--force" with this version.

 * "git help -a" now gives verbose output (same as "git help -av").
   Those who want the old output may say "git help --no-verbose -a"..

 * "git cpn --help", when "cpn" is an alias to, say, "cherry-pick -n",
   reported only the alias expansion of "cpn" in earlier versions of
   Git.  It now runs "git cherry-pick --help" to show the manual page
   of the command, while sending the alias expansion to the standard
   error stream.

 * "git send-email" learned to grab address-looking string on any
   trailer whose name ends with "-by". This is a backward-incompatible
   change.  Adding "--suppress-cc=misc-by" on the command line, or
   setting sendemail.suppresscc configuration variable to "misc-by",
   can be used to disable this behaviour.


Updates since v2.19
-------------------

UI, Workflows & Features

 * Running "git clone" against a project that contain two files with
   pathnames that differ only in cases on a case insensitive
   filesystem would result in one of the files lost because the
   underlying filesystem is incapable of holding both at the same
   time.  An attempt is made to detect such a case and warn.

 * "git checkout -b newbranch [HEAD]" should not have to do as much as
   checking out a commit different from HEAD.  An attempt is made to
   optimize this special case.

 * "git rev-list --stdin </dev/null" used to be an error; it now shows
   no output without an error.  "git rev-list --stdin --default HEAD"
   still falls back to the given default when nothing is given on the
   standard input.

 * Lift code from GitHub to restrict delta computation so that an
   object that exists in one fork is not made into a delta against
   another object that does not appear in the same forked repository.

 * "git format-patch" learned new "--interdiff" and "--range-diff"
   options to explain the difference between this version and the
   previous attempt in the cover letter (or after the three-dashes as
   a comment).

 * "git mailinfo" used in "git am" learned to make a best-effort
   recovery of a patch corrupted by MUA that sends text/plain with
   format=flawed option.
   (merge 3aa4d81f88 rs/mailinfo-format-flowed later to maint).

 * The rules used by "git push" and "git fetch" to determine if a ref
   can or cannot be updated were inconsistent; specifically, fetching
   to update existing tags were allowed even though tags are supposed
   to be unmoving anchoring points.  "git fetch" was taught to forbid
   updates to existing tags without the "--force" option.

 * "git multi-pack-index" learned to detect corruption in the .midx
   file it uses, and this feature has been integrated into "git fsck".

 * Generation of (experimental) commit-graph files have so far been
   fairly silent, even though it takes noticeable amount of time in a
   meaningfully large repository.  The users will now see progress
   output.

 * The minimum version of Windows supported by Windows port of Git is
   now set to Vista.

 * The completion script (in contrib/) learned to complete a handful of
   options "git stash list" command takes.

 * The completion script (in contrib/) learned that "git fetch
   --multiple" only takes remote names as arguments and no refspecs.

 * "git status" learns to show progress bar when refreshing the index
   takes a long time.
   (merge ae9af12287 nd/status-refresh-progress later to maint).

 * "git help -a" and "git help -av" give different pieces of
   information, and generally the "verbose" version is more friendly
   to the new users.  "git help -a" by default now uses the more
   verbose output (with "--no-verbose", you can go back to the
   original).  Also "git help -av" now lists aliases and external
   commands, which it did not used to.

 * Unlike "grep", "git grep" by default recurses to the whole tree.
   The command learned "git grep --recursive" option, so that "git
   grep --no-recursive" can serve as a synonym to setting the
   max-depth to 0.

 * When pushing into a repository that borrows its objects from an
   alternate object store, "git receive-pack" that responds to the
   push request on the other side lists the tips of refs in the
   alternate to reduce the amount of objects transferred.  This
   sometimes is detrimental when the number of refs in the alternate
   is absurdly large, in which case the bandwidth saved in potentially
   fewer objects transferred is wasted in excessively large ref
   advertisement.  The alternate refs that are advertised are now
   configurable with a pair of configuration variables.

 * "git cmd --help" when "cmd" is aliased used to only say "cmd is
   aliased to ...".  Now it shows that to the standard error stream
   and runs "git $cmd --help" where $cmd is the first word of the
   alias expansion.

 * The documentation of "git gc" has been updated to mention that it
   is no longer limited to "pruning away crufts" but also updates
   ancillary files like commit-graph as a part of repository
   optimization.

 * "git p4 unshelve" improvements.

 * The logic to select the default user name and e-mail on Windows has
   been improved.
   (merge 501afcb8b0 js/mingw-default-ident later to maint).

 * The "rev-list --filter" feature learned to exclude all trees via
   "tree:0" filter.

 * "git send-email" learned to grab address-looking string on any
   trailer whose name ends with "-by"; --suppress-cc=misc-by on the
   command line, or setting sendemail.suppresscc configuration
   variable to "misc-by", can be used to disable this behaviour.

 * Developer builds now uses -Wunused-function compilation option.

 * One of our CI tests to run with "unusual/experimental/random"
   settings now also uses commit-graph and midx.

 * "git mergetool" learned to take the "--[no-]gui" option, just like
   "git difftool" does.

 * "git rebase -i" learned a new insn, 'break', that the user can
   insert in the to-do list.  Upon hitting it, the command returns
   control back to the user.

 * New "--pretty=format:" placeholders %GF and %GP that show the GPG
   key fingerprints have been invented.

 * On platforms with recent cURL library, http.sslBackend configuration
   variable can be used to choose a different SSL backend at runtime.
   The Windows port uses this mechanism to switch between OpenSSL and
   Secure Channel while talking over the HTTPS protocol.

 * "git send-email" learned to disable SMTP authentication via the
   "--smtp-auth=none" option, even when the smtp username is given
   (which turns the authentication on by default).

 * A fourth class of configuration files (in addition to the
   traditional "system wide", "per user in the $HOME directory" and
   "per repository in the $GIT_DIR/config") has been introduced so
   that different worktrees that share the same repository (hence the
   same $GIT_DIR/config file) can use different customization.

 * A pattern with '**' that does not have a slash on either side used
   to be an invalid one, but the code now treats such double-asterisks
   the same way as two normal asterisks that happen to be adjacent to
   each other.
   (merge e5bbe09e88 nd/wildmatch-double-asterisk later to maint).

 * The "--no-patch" option, which can be used to get a high-level
   overview without the actual line-by-line patch difference shown, of
   the "range-diff" command was earlier broken, which has been
   corrected.

 * The recently merged "rebase in C" has an escape hatch to use the
   scripted version when necessary, but it hasn't been documented,
   which has been corrected.


Performance, Internal Implementation, Development Support etc.

 * When there are too many packfiles in a repository (which is not
   recommended), looking up an object in these would require
   consulting many pack .idx files; a new mechanism to have a single
   file that consolidates all of these .idx files is introduced.

 * "git submodule update" is getting rewritten piece-by-piece into C.

 * The code for computing history reachability has been shuffled,
   obtained a bunch of new tests to cover them, and then being
   improved.

 * The unpack_trees() API used in checking out a branch and merging
   walks one or more trees along with the index.  When the cache-tree
   in the index tells us that we are walking a tree whose flattened
   contents is known (i.e. matches a span in the index), as linearly
   scanning a span in the index is much more efficient than having to
   open tree objects recursively and listing their entries, the walk
   can be optimized, which has been done.

 * When creating a thin pack, which allows objects to be made into a
   delta against another object that is not in the resulting pack but
   is known to be present on the receiving end, the code learned to
   take advantage of the reachability bitmap; this allows the server
   to send a delta against a base beyond the "boundary" commit.

 * spatch transformation to replace boolean uses of !hashcmp() to
   newly introduced oideq() is added, and applied, to regain
   performance lost due to support of multiple hash algorithms.

 * Fix a bug in which the same path could be registered under multiple
   worktree entries if the path was missing (for instance, was removed
   manually).  Also, as a convenience, expand the number of cases in
   which --force is applicable.

 * Split Documentation/config.txt for easier maintenance.
   (merge 6014363f0b nd/config-split later to maint).

 * Test helper binaries clean-up.
   (merge c9a1f4161f nd/test-tool later to maint).

 * Various tests have been updated to make it easier to swap the
   hash function used for object identification.
   (merge ae0c89d41b bc/hash-independent-tests later to maint).

 * Update fsck.skipList implementation and documentation.
   (merge 371a655074 ab/fsck-skiplist later to maint).

 * An alias that expands to another alias has so far been forbidden,
   but now it is allowed to create such an alias.

 * Various test scripts have been updated for style and also correct
   handling of exit status of various commands.

 * "gc --auto" ended up calling exit(-1) upon error, which has been
   corrected to use exit(1).  Also the error reporting behaviour when
   daemonized has been updated to exit with zero status when stopping
   due to a previously discovered error (which implies there is no
   point running gc to improve the situation); we used to exit with
   failure in such a case.

 * Various codepaths in the core-ish part learned to work on an
   arbitrary in-core index structure, not necessarily the default
   instance "the_index".
   (merge b3c7eef9b0 nd/the-index later to maint).

 * Code clean-up in the internal machinery used by "git status" and
   "git commit --dry-run".
   (merge 73ba5d78b4 ss/wt-status-committable later to maint).

 * Some environment variables that control the runtime options of Git
   used during tests are getting renamed for consistency.
   (merge 4231d1ba99 bp/rename-test-env-var later to maint).

 * A pair of new extensions to the index file have been introduced.
   They allow the index file to be read in parallel for performance.

 * The oidset API was built on top of the oidmap API which in turn is
   on the hashmap API.  Replace the implementation to build on top of
   the khash API and gain performance.

 * Over some transports, fetching objects with an exact commit object
   name can be done without first seeing the ref advertisements.  The
   code has been optimized to exploit this.

 * In a partial clone that will lazily be hydrated from the
   originating repository, we generally want to avoid "does this
   object exist (locally)?" on objects that we deliberately omitted
   when we created the clone.  The cache-tree codepath (which is used
   to write a tree object out of the index) however insisted that the
   object exists, even for paths that are outside of the partial
   checkout area.  The code has been updated to avoid such a check.

 * To help developers, an EditorConfig file that attempts to follow
   the project convention has been added.
   (merge b548d698a0 bc/editorconfig later to maint).

 * The result of coverage test can be combined with "git blame" to
   check the test coverage of code introduced recently with a new
   'coverage-diff' tool (in contrib/).
   (merge 783faedd65 ds/coverage-diff later to maint).

 * An experiment to fuzz test a few areas, hopefully we can gain more
   coverage to various areas.

 * More codepaths are moving away from hardcoded hash sizes.

 * The way the Windows port figures out the current directory has been
   improved.

 * The way DLLs are loaded on the Windows port has been improved.

 * Some tests have been reorganized and renamed; "ls t/" now gives a
   better overview of what is tested for these scripts than before.

 * "git rebase" and "git rebase -i" have been reimplemented in C.

 * Windows port learned to use nano-second resolution file timestamps.

 * The overly large Documentation/config.txt file have been split into
   million little pieces.  This potentially allows each individual piece
   included into the manual page of the command it affects more easily.

 * Replace three string-list instances used as look-up tables in "git
   fetch" with hashmaps.

 * Unify code to read the author-script used in "git am" and the
   commands that use the sequencer machinery, e.g. "git rebase -i".

 * In preparation to the day when we can deprecate and remove the
   "rebase -p", make sure we can skip and later remove tests for
   it.

 * The history traversal used to implement the tag-following has been
   optimized by introducing a new helper.

 * The helper function to refresh the cached stat information in the
   in-core index has learned to perform the lstat() part of the
   operation in parallel on multi-core platforms.

 * The code to traverse objects for reachability, used to decide what
   objects are unreferenced and expendable, have been taught to also
   consider per-worktree refs of other worktrees as starting points to
   prevent data loss.

 * "git add" needs to internally run "diff-files" equivalent, and the
   codepath learned the same optimization as "diff-files" has to run
   lstat(2) in parallel to find which paths have been updated in the
   working tree.

 * The procedure to install dependencies before testing at Travis CI
   is getting revamped for both simplicity and flexibility, taking
   advantage of the recent move to the vm-based environment.

 * The support for format-patch (and send-email) by the command-line
   completion script (in contrib/) has been simplified a bit.

 * The revision walker machinery learned to take advantage of the
   commit generation numbers stored in the commit-graph file.

 * The codebase has been cleaned up to reduce "#ifndef NO_PTHREADS".

 * The way -lcurl library gets linked has been simplified by taking
   advantage of the fact that we can just ask curl-config command how.

 * Various functions have been audited for "-Wunused-parameter" warnings
   and bugs in them got fixed.

 * A sanity check for start-up sequence has been added in the config
   API codepath.

 * The build procedure to link for fuzzing test has been made
   customizable with a new Makefile variable.

 * The way "git rebase" parses and forwards the command line options
   meant for underlying "git am" has been revamped, which fixed for
   options with parameters that were not passed correctly.

 * Our testing framework uses a special i18n "poisoned localization"
   feature to find messages that ought to stay constant but are
   incorrectly marked to be translated.  This feature has been made
   into a runtime option (it used to be a compile-time option).

 * "git push" used to check ambiguities between object-names and
   refnames while processing the list of refs' old and new values,
   which was unnecessary (as it knew that it is feeding raw object
   names).  This has been optimized out.

 * The xcurl_off_t() helper function is used to cast size_t to
   curl_off_t, but some compilers gave warnings against the code to
   ensure the casting is done without wraparound, when size_t is
   narrower than curl_off_t.  This warning has been squelched.

 * Code preparation to replace ulong vars with size_t vars where
   appropriate continues.

 * The "test installed Git" mode of our test suite has been updated to
   work better.

 * A coding convention around the Coccinelle semantic patches to have
   two classes to ease code migration process has been proposed and
   its support has been added to the Makefile.


Fixes since v2.19
-----------------

 * "git interpret-trailers" and its underlying machinery had a buggy
   code that attempted to ignore patch text after commit log message,
   which triggered in various codepaths that will always get the log
   message alone and never get such an input.
   (merge 66e83d9b41 jk/trailer-fixes later to maint).

 * Malformed or crafted data in packstream can make our code attempt
   to read or write past the allocated buffer and abort, instead of
   reporting an error, which has been fixed.

 * "git rebase -i" did not clear the state files correctly when a run
   of "squash/fixup" is aborted and then the user manually amended the
   commit instead, which has been corrected.
   (merge 10d2f35436 js/rebase-i-autosquash-fix later to maint).

 * When fsmonitor is in use, after operation on submodules updates
   .gitmodules, we lost track of the fact that we did so and relied on
   stale fsmonitor data.
   (merge 43f1180814 bp/mv-submodules-with-fsmonitor later to maint).

 * Fix for a long-standing bug that leaves the index file corrupt when
   it shrinks during a partial commit.
   (merge 6c003d6ffb jk/reopen-tempfile-truncate later to maint).

 * Further fix for O_APPEND emulation on Windows
   (merge eeaf7ddac7 js/mingw-o-append later to maint).

 * A corner case bugfix in "git rerere" code.
   (merge ad2bf0d9b4 en/rerere-multi-stage-1-fix later to maint).

 * "git add ':(attr:foo)'" is not supported and is supposed to be
   rejected while the command line arguments are parsed, but we fail
   to reject such a command line upfront.
   (merge 84d938b732 nd/attr-pathspec-fix later to maint).

 * Recent update broke the reachability algorithm when refs (e.g.
   tags) that point at objects that are not commit were involved,
   which has been fixed.

 * "git rebase" etc. in Git 2.19 fails to abort when given an empty
   commit log message as result of editing, which has been corrected.
   (merge a3ec9eaf38 en/sequencer-empty-edit-result-aborts later to maint).

 * The code to backfill objects in lazily cloned repository did not
   work correctly, which has been corrected.
   (merge e68302011c jt/lazy-object-fetch-fix later to maint).

 * Update error messages given by "git remote" and make them consistent.
   (merge 5025425dff ms/remote-error-message-update later to maint).

 * "git update-ref" learned to make both "--no-deref" and "--stdin"
   work at the same time.
   (merge d345e9fbe7 en/update-ref-no-deref-stdin later to maint).

 * Recently added "range-diff" had a corner-case bug to cause it
   segfault, which has been corrected.
   (merge e467a90c7a tg/range-diff-corner-case-fix later to maint).

 * The recently introduced commit-graph auxiliary data is incompatible
   with mechanisms such as replace & grafts that "breaks" immutable
   nature of the object reference relationship.  Disable optimizations
   based on its use (and updating existing commit-graph) when these
   incompatible features are in use in the repository.
   (merge 829a321569 ds/commit-graph-with-grafts later to maint).

 * The mailmap file update.
   (merge 255eb03edf jn/mailmap-update later to maint).

 * The code in "git status" sometimes hit an assertion failure.  This
   was caused by a structure that was reused without cleaning the data
   used for the first run, which has been corrected.
   (merge 3e73cc62c0 en/status-multiple-renames-to-the-same-target-fix later to maint).

 * "git fetch $repo $object" in a partial clone did not correctly
   fetch the asked-for object that is referenced by an object in
   promisor packfile, which has been fixed.

 * A corner-case bugfix.
   (merge c5cbb27cb5 sm/show-superproject-while-conflicted later to maint).

 * Various fixes to "diff --color-moved-ws".

 * A partial clone that is configured to lazily fetch missing objects
   will on-demand issue a "git fetch" request to the originating
   repository to fill not-yet-obtained objects.  The request has been
   optimized for requesting a tree object (and not the leaf blob
   objects contained in it) by telling the originating repository that
   no blobs are needed.
   (merge 4c7f9567ea jt/non-blob-lazy-fetch later to maint).

 * The codepath to support the experimental split-index mode had
   remaining "racily clean" issues fixed.
   (merge 4c490f3d32 sg/split-index-racefix later to maint).

 * "git log --graph" showing an octopus merge sometimes miscounted the
   number of display columns it is consuming to show the merge and its
   parent commits, which has been corrected.
   (merge 04005834ed np/log-graph-octopus-fix later to maint).

 * "git range-diff" did not work well when the compared ranges had
   changes in submodules and the "--submodule=log" was used.

 * The implementation of run_command() API on the UNIX platforms had a
   bug that caused a command not on $PATH to be found in the current
   directory.
   (merge f67b980771 jk/run-command-notdot later to maint).

 * A mutex used in "git pack-objects" were not correctly initialized
   and this caused "git repack" to dump core on Windows.
   (merge 34204c8166 js/pack-objects-mutex-init-fix later to maint).

 * Under certain circumstances, "git diff D:/a/b/c D:/a/b/d" on
   Windows would strip initial parts from the paths because they
   were not recognized as absolute, which has been corrected.
   (merge ffd04e92e2 js/diff-notice-has-drive-prefix later to maint).

 * The receive.denyCurrentBranch=updateInstead codepath kicked in even
   when the push should have been rejected due to other reasons, such
   as it does not fast-forward or the update-hook rejects it, which
   has been corrected.
   (merge b072a25fad jc/receive-deny-current-branch-fix later to maint).

 * The logic to determine the archive type "git archive" uses did not
   correctly kick in for "git archive --remote", which has been
   corrected.

 * "git repack" in a shallow clone did not correctly update the
   shallow points in the repository, leading to a repository that
   does not pass fsck.
   (merge 5dcfbf564c js/shallow-and-fetch-prune later to maint).

 * Some codepaths failed to form a proper URL when .gitmodules record
   the URL to a submodule repository as relative to the repository of
   superproject, which has been corrected.
   (merge e0a862fdaf sb/submodule-url-to-absolute later to maint).

 * "git fetch" over protocol v2 into a shallow repository failed to
   fetch full history behind a new tip of history that was diverged
   before the cut-off point of the history that was previously fetched
   shallowly.

 * The command line completion machinery (in contrib/) has been
   updated to allow the completion script to tweak the list of options
   that are reported by the parse-options machinery correctly.
   (merge 276b49ff34 nd/completion-negation later to maint).

 * Operations on promisor objects make sense in the context of only a
   small subset of the commands that internally use the revisions
   machinery, but the "--exclude-promisor-objects" option were taken
   and led to nonsense results by commands like "log", to which it
   didn't make much sense.  This has been corrected.
   (merge 669b1d2aae md/exclude-promisor-objects-fix later to maint).

 * The "container" mode of TravisCI is going away.  Our .travis.yml
   file is getting prepared for the transition.
   (merge 32ee384be8 ss/travis-ci-force-vm-mode later to maint).

 * Our test scripts can now take the '-V' option as a synonym for the
   '--verbose-log' option.
   (merge a5f52c6dab sg/test-verbose-log later to maint).

 * A regression in Git 2.12 era made "git fsck" fall into an infinite
   loop while processing truncated loose objects.
   (merge 18ad13e5b2 jk/detect-truncated-zlib-input later to maint).

 * "git ls-remote $there foo" was broken by recent update for the
   protocol v2 and stopped showing refs that match 'foo' that are not
   refs/{heads,tags}/foo, which has been fixed.
   (merge 6a139cdd74 jk/proto-v2-ref-prefix-fix later to maint).

 * Additional comment on a tricky piece of code to help developers.
   (merge 0afbe3e806 jk/stream-pack-non-delta-clarification later to maint).

 * A couple of tests used to leave the repository in a state that is
   deliberately corrupt, which have been corrected.
   (merge aa984dbe5e ab/pack-tests-cleanup later to maint).

 * The submodule support has been updated to read from the blob at
   HEAD:.gitmodules when the .gitmodules file is missing from the
   working tree.
   (merge 2b1257e463 ao/submodule-wo-gitmodules-checked-out later to maint).

 * "git fetch" was a bit loose in parsing responses from the other side
   when talking over the protocol v2.

 * "git rev-parse --exclude=* --branches --branches"  (i.e. first
   saying "add only things that do not match '*' out of all branches"
   and then adding all branches, without any exclusion this time")
   worked as expected, but "--exclude=* --all --all" did not work the
   same way, which has been fixed.
   (merge 5221048092 ag/rev-parse-all-exclude-fix later to maint).

 * "git send-email --transfer-encoding=..." in recent versions of Git
   sometimes produced an empty "Content-Transfer-Encoding:" header,
   which has been corrected.
   (merge 3c88e46f1a al/send-email-auto-cte-fixup later to maint).

 * The interface into "xdiff" library used to discover the offset and
   size of a generated patch hunk by first formatting it into the
   textual hunk header "@@ -n,m +k,l @@" and then parsing the numbers
   out.  A new interface has been introduced to allow callers a more
   direct access to them.
   (merge 5eade0746e jk/xdiff-interface later to maint).

 * Pathspec matching against a tree object were buggy when negative
   pathspec elements were involved, which has been fixed.
   (merge b7845cebc0 nd/tree-walk-path-exclusion later to maint).

 * "git merge" and "git pull" that merges into an unborn branch used
   to completely ignore "--verify-signatures", which has been
   corrected.
   (merge 01a31f3bca jk/verify-sig-merge-into-void later to maint).

 * "git rebase --autostash" did not correctly re-attach the HEAD at times.

 * "rev-parse --exclude=<pattern> --branches=<pattern>" etc. did not
   quite work, which has been corrected.
   (merge 9ab9b5df0e ra/rev-parse-exclude-glob later to maint).

 * When editing a patch in a "git add -i" session, a hunk could be
   made to no-op.  The "git apply" program used to reject a patch with
   such a no-op hunk to catch user mistakes, but it is now updated to
   explicitly allow a no-op hunk in an edited patch.
   (merge 22cb3835b9 js/apply-recount-allow-noop later to maint).

 * The URL to an MSDN page in a comment has been updated.
   (merge 2ef2ae2917 js/mingw-msdn-url later to maint).

 * "git ls-remote --sort=<thing>" can feed an object that is not yet
   available into the comparison machinery and segfault, which has
   been corrected to check such a request upfront and reject it.

 * When "git bundle" aborts due to an empty commit ranges
   (i.e. resulting in an empty pack), it left a file descriptor to an
   lockfile open, which resulted in leftover lockfile on Windows where
   you cannot remove a file with an open file descriptor.  This has
   been corrected.
   (merge 2c8ee1f53c jk/close-duped-fd-before-unlock-for-bundle later to maint).

 * "git format-patch --stat=<width>" can be used to specify the width
   used by the diffstat (shown in the cover letter).
   (merge 284aeb7e60 nd/format-patch-cover-letter-stat-width later to maint).

 * The way .git/index and .git/sharedindex* files were initially
   created gave these files different perm bits until they were
   adjusted for shared repository settings.  This was made consistent.
   (merge c9d6c78870 cc/shared-index-permbits later to maint).

 * "git rebase --stat" to transplant a piece of history onto a totally
   unrelated history were not working before and silently showed wrong
   result.  With the recent reimplementation in C, it started to instead
   die with an error message, as the original logic was not prepared
   to cope with this case.  This has now been fixed.

 * The advice message to tell the user to migrate an existing graft
   file to the replace system when a graft file was read was shown
   even when "git replace --convert-graft-file" command, which is the
   way the message suggests to use, was running, which made little
   sense.
   (merge 8821e90a09 ab/replace-graft-with-replace-advice later to maint).

 * "git diff --raw" lost ellipses to adjust the output columns for
   some time now, but the documentation still showed them.

 * Code cleanup, docfix, build fix, etc.
   (merge 96a7501aad ts/doc-build-manpage-xsl-quietly later to maint).
   (merge b9b07efdb2 tg/conflict-marker-size later to maint).
   (merge fa0aeea770 sg/doc-trace-appends later to maint).
   (merge d64324cb60 tb/void-check-attr later to maint).
   (merge c3b9bc94b9 en/double-semicolon-fix later to maint).
   (merge 79336116f5 sg/t3701-tighten-trace later to maint).
   (merge 801fa63a90 jk/dev-build-format-security later to maint).
   (merge 0597dd62ba sb/string-list-remove-unused later to maint).
   (merge db2d36fad8 bw/protocol-v2 later to maint).
   (merge 456d7cd3a9 sg/split-index-test later to maint).
   (merge 7b6057c852 tq/refs-internal-comment-fix later to maint).
   (merge 29e8dc50ad tg/t5551-with-curl-7.61.1 later to maint).
   (merge 55f6bce2c9 fe/doc-updates later to maint).
   (merge 7987d2232d jk/check-everything-connected-is-long-gone later to maint).
   (merge 4ba3c9be47 dz/credential-doc-url-matching-rules later to maint).
   (merge 4c399442f7 ma/commit-graph-docs later to maint).
   (merge fc0503b04e ma/t1400-undebug-test later to maint).
   (merge e56b53553a nd/packobjectshook-doc-fix later to maint).
   (merge c56170a0c4 ma/mailing-list-address-in-git-help later to maint).
   (merge 6e8fc70fce rs/sequencer-oidset-insert-avoids-dups later to maint).
   (merge ad0b8f9575 mw/doc-typofixes later to maint).
   (merge d9f079ad1a jc/how-to-document-api later to maint).
   (merge b1492bf315 ma/t7005-bash-workaround later to maint).
   (merge ac1f98a0df du/rev-parse-is-plumbing later to maint).
   (merge ca8ed443a5 mm/doc-no-dashed-git later to maint).
   (merge ce366a8144 du/get-tar-commit-id-is-plumbing later to maint).
   (merge 61018fe9e0 du/cherry-is-plumbing later to maint).
   (merge c7e5fe79b9 sb/strbuf-h-update later to maint).
   (merge 8d2008196b tq/branch-create-wo-branch-get later to maint).
   (merge 2e3c894f4b tq/branch-style-fix later to maint).
   (merge c5d844af9c sg/doc-show-branch-typofix later to maint).
   (merge 081d91618b ah/doc-updates later to maint).
   (merge b84c783882 jc/cocci-preincr later to maint).
   (merge 5e495f8122 uk/merge-subtree-doc-update later to maint).
   (merge aaaa881822 jk/uploadpack-packobjectshook-fix later to maint).
   (merge 3063477445 tb/char-may-be-unsigned later to maint).
   (merge 8c64bc9420 sg/test-rebase-editor-fix later to maint).
   (merge 71571cd7d6 ma/sequencer-do-reset-saner-loop-termination later to maint).
   (merge 9a4cb8781e cb/notes-freeing-always-null-fix later to maint).
   (merge 3006f5ee16 ma/reset-doc-rendering-fix later to maint).
   (merge 4c2eb06419 sg/daemon-test-signal-fix later to maint).
   (merge d27525e519 ss/msvc-strcasecmp later to maint).

----------------------------------------------------------------

Changes since v2.19.0 are as follows:

Aaron Lindsay (1):
      send-email: avoid empty transfer encoding header

Alban Gruin (21):
      sequencer: make three functions and an enum from sequencer.c public
      rebase -i: rewrite append_todo_help() in C
      editor: add a function to launch the sequence editor
      rebase -i: rewrite the edit-todo functionality in C
      sequencer: add a new function to silence a command, except if it fails
      rebase -i: rewrite setup_reflog_action() in C
      rebase -i: rewrite checkout_onto() in C
      sequencer: refactor append_todo_help() to write its message to a buffer
      sequencer: change the way skip_unnecessary_picks() returns its result
      t3404: todo list with commented-out commands only aborts
      rebase -i: rewrite complete_action() in C
      rebase -i: remove unused modes and functions
      rebase -i: implement the logic to initialize $revisions in C
      rebase -i: rewrite the rest of init_revisions_and_shortrevisions() in C
      rebase -i: rewrite write_basic_state() in C
      rebase -i: rewrite init_basic_state() in C
      rebase -i: implement the main part of interactive rebase as a builtin
      rebase--interactive2: rewrite the submodes of interactive rebase in C
      rebase -i: remove git-rebase--interactive.sh
      rebase -i: move rebase--helper modes to rebase--interactive
      p3400: replace calls to `git checkout -b' by `git checkout -B'

Alexander Pyhalov (1):
      t7005-editor: quote filename to fix whitespace-issue

Andreas Gruenbacher (1):
      rev-parse: clear --exclude list after 'git rev-parse --all'

Andreas Heiduk (6):
      doc: clarify boundaries of 'git worktree list --porcelain'
      doc: fix ASCII art tab spacing
      doc: fix inappropriate monospace formatting
      doc: fix descripion for 'git tag --format'
      doc: fix indentation of listing blocks in gitweb.conf.txt
      doc: fix formatting in git-update-ref

Anton Serbulov (1):
      mingw: fix getcwd when the parent directory cannot be queried

Antonio Ospite (10):
      submodule: add a print_config_from_gitmodules() helper
      submodule: factor out a config_set_in_gitmodules_file_gently function
      t7411: merge tests 5 and 6
      t7411: be nicer to future tests and really clean things up
      submodule--helper: add a new 'config' subcommand
      submodule: use the 'submodule--helper config' command
      t7506: clean up .gitmodules properly before setting up new scenario
      submodule: add a helper to check if it is safe to write to .gitmodules
      submodule: support reading .gitmodules when it's not in the working tree
      t/helper: add test-submodule-nested-repo-config

Ben Peart (19):
      checkout: optimize "git checkout -b <new_branch>"
      git-mv: allow submodules and fsmonitor to work together
      t/README: correct spelling of "uncommon"
      preload-index: use git_env_bool() not getenv() for customization
      fsmonitor: update GIT_TEST_FSMONITOR support
      read-cache: update TEST_GIT_INDEX_VERSION support
      preload-index: update GIT_FORCE_PRELOAD_TEST support
      read-cache: clean up casting and byte decoding
      eoie: add End of Index Entry (EOIE) extension
      config: add new index.threads config setting
      read-cache: load cache extensions on a worker thread
      ieot: add Index Entry Offset Table (IEOT) extension
      read-cache: load cache entries on worker threads
      reset: don't compute unstaged changes after reset when --quiet
      reset: add new reset.quiet config setting
      reset: warn when refresh_index() takes more than 2 seconds
      speed up refresh_index() by utilizing preload_index()
      add: speed up cmd_add() by utilizing read_cache_preload()
      refresh_index: remove unnecessary calls to preload_index()

Brandon Williams (1):
      config: document value 2 for protocol.version

Brendan Forster (1):
      http: add support for disabling SSL revocation checks in cURL

Carlo Marcelo Arenas Belón (8):
      unpack-trees: avoid dead store for struct progress
      multi-pack-index: avoid dead store for struct progress
      read-cache: use of memory after it is freed
      commit-slabs: move MAYBE_UNUSED out
      khash: silence -Wunused-function for delta-islands
      compat: make sure git_mmap is not expected to write
      sequencer: cleanup for gcc warning in non developer mode
      builtin/notes: remove unnecessary free

Christian Couder (3):
      pack-objects: refactor code into compute_layer_order()
      pack-objects: move tree_depth into 'struct packing_data'
      pack-objects: move 'layer' into 'struct packing_data'

Christian Hesse (2):
      subtree: add build targets 'man' and 'html'
      subtree: make install targets depend on build targets

Daniels Umanovskis (3):
      doc: move git-rev-parse from porcelain to plumbing
      doc: move git-get-tar-commit-id to plumbing
      doc: move git-cherry to plumbing

David Zych (1):
      doc: clarify gitcredentials path component matching

Denton Liu (3):
      mergetool: accept -g/--[no-]gui as arguments
      completion: support `git mergetool --[no-]gui`
      doc: document diff/merge.guitool config keys

Derrick Stolee (93):
      multi-pack-index: add design document
      multi-pack-index: add format details
      multi-pack-index: add builtin
      multi-pack-index: add 'write' verb
      midx: write header information to lockfile
      multi-pack-index: load into memory
      t5319: expand test data
      packfile: generalize pack directory list
      multi-pack-index: read packfile list
      multi-pack-index: write pack names in chunk
      midx: read pack names into array
      midx: sort and deduplicate objects from packfiles
      midx: write object ids in a chunk
      midx: write object id fanout chunk
      midx: write object offsets
      config: create core.multiPackIndex setting
      midx: read objects from multi-pack-index
      midx: use midx in abbreviation calculations
      midx: use existing midx when writing new one
      midx: use midx in approximate_object_count
      midx: prevent duplicate packfile loads
      packfile: skip loading index if in multi-pack-index
      midx: clear midx on repack
      commit-reach: move walk methods from commit.c
      commit.h: remove method declarations
      commit-reach: move ref_newer from remote.c
      commit-reach: move commit_contains from ref-filter
      upload-pack: make reachable() more generic
      upload-pack: refactor ok_to_give_up()
      upload-pack: generalize commit date cutoff
      commit-reach: move can_all_from_reach_with_flags
      test-reach: create new test tool for ref_newer
      test-reach: test in_merge_bases
      test-reach: test is_descendant_of
      test-reach: test get_merge_bases_many
      test-reach: test reduce_heads
      test-reach: test can_all_from_reach_with_flags
      test-reach: test commit_contains
      commit-reach: replace ref_newer logic
      commit-reach: make can_all_from_reach... linear
      commit-reach: use can_all_from_reach
      multi-pack-index: provide more helpful usage info
      multi-pack-index: store local property
      midx: mark bad packed objects
      midx: stop reporting garbage
      midx: fix bug that skips midx with alternates
      packfile: add all_packs list
      treewide: use get_all_packs
      midx: test a few commands that use get_all_packs
      pack-objects: consider packs in multi-pack-index
      commit-graph: update design document
      test-repository: properly init repo
      commit-graph: not compatible with replace objects
      commit-graph: not compatible with grafts
      commit-graph: not compatible with uninitialized repo
      commit-graph: close_commit_graph before shallow walk
      commit-graph: define GIT_TEST_COMMIT_GRAPH
      t3206-range-diff.sh: cover single-patch case
      t5318: use test_oid for HASH_LEN
      multi-pack-index: add 'verify' verb
      multi-pack-index: verify bad header
      multi-pack-index: verify corrupt chunk lookup table
      multi-pack-index: verify packname order
      multi-pack-index: verify missing pack
      multi-pack-index: verify oid fanout order
      multi-pack-index: verify oid lookup order
      multi-pack-index: fix 32-bit vs 64-bit size check
      multi-pack-index: verify object offsets
      multi-pack-index: report progress during 'verify'
      fsck: verify multi-pack-index
      commit-reach: properly peel tags
      commit-reach: fix memory and flag leaks
      commit-reach: cleanups in can_all_from_reach...
      commit-graph: clean up leaked memory during write
      commit-graph: reduce initial oid allocation
      midx: fix broken free() in close_midx()
      contrib: add coverage-diff script
      ci: add optional test variables
      commit-reach: fix first-parent heuristic
      midx: close multi-pack-index on repack
      multi-pack-index: define GIT_TEST_MULTI_PACK_INDEX
      packfile: close multi-pack-index in close_all_packs
      prio-queue: add 'peek' operation
      test-reach: add run_three_modes method
      test-reach: add rev-list tests
      revision.c: begin refactoring --topo-order logic
      commit/revisions: bookkeeping before refactoring
      revision.c: generation-based topo-order algorithm
      t6012: make rev-list tests more interesting
      commit-reach: implement get_reachable_subset
      test-reach: test get_reachable_subset
      remote: make add_missing_tags() linear
      pack-objects: ignore ambiguous object warnings

Elijah Newren (14):
      Remove superfluous trailing semicolons
      t4200: demonstrate rerere segfault on specially crafted merge
      rerere: avoid buffer overrun
      update-ref: fix type of update_flags variable to match its usage
      update-ref: allow --no-deref with --stdin
      sequencer: fix --allow-empty-message behavior, make it smarter
      merge-recursive: set paths correctly when three-way merging content
      merge-recursive: avoid wrapper function when unnecessary and wasteful
      merge-recursive: remove final remaining caller of merge_file_one()
      merge-recursive: rename merge_file_1() and merge_content()
      commit: fix erroneous BUG, 'multiple renames on the same target? how?'
      merge-recursive: improve auto-merging messages with path collisions
      merge-recursive: avoid showing conflicts with merge branch before HEAD
      fsck: move fsck_head_link() to get_default_heads() to avoid some globals

Eric Sunshine (26):
      format-patch: allow additional generated content in make_cover_letter()
      format-patch: add --interdiff option to embed diff in cover letter
      format-patch: teach --interdiff to respect -v/--reroll-count
      interdiff: teach show_interdiff() to indent interdiff
      log-tree: show_log: make commentary block delimiting reusable
      format-patch: allow --interdiff to apply to a lone-patch
      range-diff: respect diff_option.file rather than assuming 'stdout'
      range-diff: publish default creation factor
      range-diff: relieve callers of low-level configuration burden
      format-patch: add --range-diff option to embed diff in cover letter
      format-patch: extend --range-diff to accept revision range
      format-patch: teach --range-diff to respect -v/--reroll-count
      format-patch: add --creation-factor tweak for --range-diff
      format-patch: allow --range-diff to apply to a lone-patch
      worktree: don't die() in library function find_worktree()
      worktree: move delete_git_dir() earlier in file for upcoming new callers
      worktree: generalize delete_git_dir() to reduce code duplication
      worktree: prepare for more checks of whether path can become worktree
      worktree: disallow adding same path multiple times
      worktree: teach 'add' to respect --force for registered but missing path
      worktree: teach 'move' to override lock when --force given twice
      worktree: teach 'remove' to override lock when --force given twice
      worktree: delete .git/worktrees if empty after 'remove'
      doc-diff: fix non-portable 'man' invocation
      doc-diff: add --clean mode to remove temporary working gunk
      doc/Makefile: drop doc-diff worktree and temporary files on "make clean"

Frederick Eaton (3):
      git-archimport.1: specify what kind of Arch we're talking about
      git-column.1: clarify initial description, provide examples
      git-describe.1: clarify that "human readable" is also git-readable

Greg Hurrell (1):
      doc: update diff-format.txt for removed ellipses in --raw

James Knight (1):
      build: link with curl-defined linker flags

Jann Horn (2):
      patch-delta: fix oob read
      patch-delta: consistently report corruption

Jean-Noël Avila (1):
      i18n: fix small typos

Jeff Hostetler (2):
      t0051: test GIT_TRACE to a windows named pipe
      mingw: fix mingw_open_append to work with named pipes

Jeff King (98):
      branch: make "-l" a synonym for "--list"
      Add delta-islands.{c,h}
      pack-objects: add delta-islands support
      repack: add delta-islands support
      t5320: tests for delta islands
      t/perf: factor boilerplate out of test_perf
      t/perf: factor out percent calculations
      t/perf: add infrastructure for measuring sizes
      t/perf: add perf tests for fetches from a bitmapped server
      pack-bitmap: save "have" bitmap from walk
      pack-objects: reuse on-disk deltas for thin "have" objects
      SubmittingPatches: mention doc-diff
      rev-list: make empty --stdin not an error
      trailer: use size_t for string offsets
      trailer: use size_t for iterating trailer list
      trailer: pass process_trailer_opts to trailer_info_get()
      interpret-trailers: tighten check for "---" patch boundary
      interpret-trailers: allow suppressing "---" divider
      pretty, ref-filter: format %(trailers) with no_divider option
      sequencer: ignore "---" divider when parsing trailers
      append_signoff: use size_t for string offsets
      coccinelle: use <...> for function exclusion
      introduce hasheq() and oideq()
      convert "oidcmp() == 0" to oideq()
      convert "hashcmp() == 0" to hasheq()
      convert "oidcmp() != 0" to "!oideq()"
      convert "hashcmp() != 0" to "!hasheq()"
      convert hashmap comparison functions to oideq()
      read-cache: use oideq() in ce_compare functions
      show_dirstat: simplify same-content check
      doc-diff: always use oids inside worktree
      test-delta: read input into a heap buffer
      t5303: test some corrupt deltas
      patch-delta: handle truncated copy parameters
      t5303: use printf to generate delta bases
      doc/git-branch: remove obsolete "-l" references
      bitmap_has_sha1_in_uninteresting(): drop BUG check
      t5310: test delta reuse with bitmaps
      traverse_bitmap_commit_list(): don't free result
      pack-bitmap: drop "loaded" flag
      reopen_tempfile(): truncate opened file
      doc-diff: force worktree add
      config.mak.dev: add -Wformat-security
      pack-objects: handle island check for "external" delta base
      receive-pack: update comment with check_everything_connected
      submodule--helper: use "--" to signal end of clone options
      submodule-config: ban submodule urls that start with dash
      submodule-config: ban submodule paths that start with a dash
      fsck: detect submodule urls starting with dash
      fsck: detect submodule paths starting with dash
      more oideq/hasheq conversions
      transport: drop refnames from for_each_alternate_ref
      test-tool: show tool list on error
      config.mak.dev: enable -Wunused-function
      run-command: mark path lookup errors with ENOENT
      t5410: use longer path for sample script
      upload-pack: fix broken if/else chain in config callback
      t1450: check large blob in trailing-garbage test
      check_stream_sha1(): handle input underflow
      cat-file: handle streaming failures consistently
      ls-remote: do not send ref prefixes for patterns
      ls-remote: pass heads/tags prefixes to transport
      read_istream_pack_non_delta(): document input handling
      xdiff: provide a separate emit callback for hunks
      xdiff-interface: provide a separate consume callback for hunks
      rev-list: handle flags for --indexed-objects
      approxidate: handle pending number for "specials"
      pathspec: handle non-terminated strings with :(attr)
      diff: avoid generating unused hunk header lines
      diff: discard hunk headers for patch-ids earlier
      diff: use hunk callback for word-diff
      combine-diff: use an xdiff hunk callback
      diff: convert --check to use a hunk callback
      range-diff: use a hunk callback
      xdiff-interface: drop parse_hunk_header()
      apply: mark include/exclude options as NONEG
      am: handle --no-patch-format option
      ls-files: mark exclude options as NONEG
      pack-objects: mark index-version option as NONEG
      cat-file: mark batch options with NONEG
      status: mark --find-renames option with NONEG
      format-patch: mark "--no-numbered" option with NONEG
      show-branch: mark --reflog option as NONEG
      tag: mark "--message" option with NONEG
      cat-file: report an error on multiple --batch options
      apply: return -1 from option callback instead of calling exit(1)
      parse-options: drop OPT_DATE()
      assert NOARG/NONEG behavior of parse-options callbacks
      midx: double-check large object write loop
      merge: extract verify_merge_signature() helper
      merge: handle --verify-signatures for unborn branch
      pull: handle --verify-signatures for unborn branch
      approxidate: fix NULL dereference in date_time()
      bundle: dup() output descriptor closer to point-of-use
      pack-objects: fix tree_depth and layer invariants
      pack-objects: zero-initialize tree_depth/layer arrays
      pack-objects: fix off-by-one in delta-island tree-depth computation
      t5562: fix perl path

Johannes Schindelin (64):
      rebase -i --autosquash: demonstrate a problem skipping the last squash
      rebase -i: be careful to wrap up fixup/squash chains
      compat/poll: prepare for targeting Windows Vista
      mingw: set _WIN32_WINNT explicitly for Git for Windows
      mingw: bump the minimum Windows version to Vista
      builtin rebase: prepare for builtin rebase -i
      rebase -i: clarify what happens on a failed `exec`
      rebase -i: introduce the 'break' command
      getpwuid(mingw): initialize the structure only once
      getpwuid(mingw): provide a better default for the user name
      mingw: use domain information for default email
      http: add support for selecting SSL backends at runtime
      pack-objects: fix typo 'detla' -> 'delta'
      pack-objects (mingw): demonstrate a segmentation fault with large deltas
      pack-objects (mingw): initialize `packing_data` mutex in the correct spot
      rebase (autostash): avoid duplicate call to state_dir_path()
      rebase (autostash): store the full OID in <state-dir>/autostash
      rebase (autostash): use an explicit OID to apply the stash
      mingw: factor out code to set stat() data
      rebase --autostash: demonstrate a problem with dirty submodules
      rebase --autostash: fix issue with dirty submodules
      mingw: load system libraries the recommended way
      mingw: ensure `getcwd()` reports the correct case
      repack: point out a bug handling stale shallow info
      shallow: offer to prune only non-existing entries
      repack -ad: prune the list of shallow commits
      http: when using Secure Channel, ignore sslCAInfo by default
      t7800: fix quoting
      mingw: reencode environment variables on the fly (UTF-16 <-> UTF-8)
      config: rename `dummy` parameter to `cb` in git_default_config()
      config: allow for platform-specific core.* config settings
      config: move Windows-specific config settings into compat/mingw.c
      mingw: unset PERL5LIB by default
      mingw: fix isatty() after dup2()
      t3404: decouple some test cases from outcomes of previous test cases
      t3418: decouple test cases from a previous `rebase -p` test case
      tests: optionally skip `git rebase -p` tests
      Windows: force-recompile git.res for differing architectures
      built-in rebase: demonstrate regression with --autostash
      built-in rebase --autostash: leave the current branch alone if possible
      Update .mailmap
      rebase -r: demonstrate bug with conflicting merges
      rebase -r: do not write MERGE_HEAD unless needed
      rebase -i: include MERGE_HEAD into files to clean up
      built-in rebase --skip/--abort: clean up stale .git/<name> files
      status: rebase and merge can be in progress at the same time
      apply --recount: allow "no-op hunks"
      rebase: consolidate clean-up code before leaving reset_head()
      rebase: prepare reset_head() for more flags
      built-in rebase: reinstate `checkout -q` behavior where appropriate
      tests: fix GIT_TEST_INSTALLED's PATH to include t/helper/
      tests: respect GIT_TEST_INSTALLED when initializing repositories
      t/lib-gettext: test installed git-sh-i18n if GIT_TEST_INSTALLED is set
      mingw: use `CreateHardLink()` directly
      rebase: really just passthru the `git am` options
      rebase: validate -C<n> and --whitespace=<mode> parameters early
      config: report a bug if git_dir exists without commondir
      tests: do not require Git to be built when testing an installed Git
      tests: explicitly use `git.exe` on Windows
      mingw: replace an obsolete link with the superseding one
      legacy-rebase: backport -C<n> and --whitespace=<option> checks
      rebase: warn about the correct tree's OID
      rebase: fix GIT_REFLOG_ACTION regression
      rebase --stat: fix when rebasing to an unrelated history

Johannes Sixt (3):
      diff: don't attempt to strip prefix from absolute Windows paths
      rebase -i: recognize short commands without arguments
      t3404-rebase-interactive: test abbreviated commands

Jonathan Nieder (9):
      gc: improve handling of errors reading gc.log
      gc: exit with status 128 on failure
      gc: do not return error for prior errors in daemonized mode
      commit-reach: correct accidental #include of C file
      mailmap: consistently normalize brian m. carlson's name
      git doc: direct bug reporters to mailing list archive
      eoie: default to not writing EOIE section
      ieot: default to not writing IEOT section
      index: make index.threads=true enable ieot and eoie

Jonathan Tan (15):
      fetch-object: unify fetch_object[s] functions
      fetch-object: set exact_oid when fetching
      connected: document connectivity in partial clones
      fetch: in partial clone, check presence of targets
      fetch-pack: avoid object flags if no_dependents
      fetch-pack: exclude blobs when lazy-fetching trees
      transport: allow skipping of ref listing
      transport: do not list refs if possible
      transport: list refs before fetch if necessary
      fetch: do not list refs if fetching only hashes
      cache-tree: skip some blob checks in partial clone
      upload-pack: make have_obj not global
      upload-pack: make want_obj not global
      upload-pack: clear flags before each v2 request
      fetch-pack: be more precise in parsing v2 response

Josh Steadmon (4):
      fuzz: add basic fuzz testing target.
      fuzz: add fuzz testing for packfile indices.
      archive: initialize archivers earlier
      Makefile: use FUZZ_CXXFLAGS for linking fuzzers

Joshua Watt (1):
      send-email: explicitly disable authentication

Junio C Hamano (36):
      Revert "doc/Makefile: drop doc-diff worktree and temporary files on "make clean""
      Initial batch post 2.19
      Second batch post 2.19
      Git 2.14.5
      Git 2.15.3
      Git 2.16.5
      Git 2.17.2
      Git 2.18.1
      Git 2.19.1
      t0000: do not get self-test disrupted by environment warnings
      CodingGuidelines: document the API in *.h files
      Declare that the next one will be named 2.20
      Third batch for 2.20
      rebase: fix typoes in error messages
      Fourth batch for 2.20
      Revert "subtree: make install targets depend on build targets"
      Fifth batch for 2.20
      receive: denyCurrentBranch=updateinstead should not blindly update
      cocci: simplify "if (++u > 1)" to "if (u++)"
      fsck: s/++i > 1/i++/
      http: give curl version warnings consistently
      Sixth batch for 2.20
      Seventh batch for 2.20
      fetch: replace string-list used as a look-up table with a hashmap
      rebase: apply cocci patch
      Eighth batch for 2.20
      Ninth batch for 2.20
      Makefile: ease dynamic-gettext-poison transition
      Tenth batch for 2.20
      Git 2.20-rc0
      RelNotes: name the release properly
      Prepare for 2.20-rc1
      Git 2.19.2
      Git 2.20-rc1
      format-patch: do not let its diff-options affect --range-diff
      Git 2.20-rc2

Karsten Blees (2):
      mingw: replace MSVCRT's fstat() with a Win32-based implementation
      mingw: implement nanosecond-precision file times

Loo Rong Jie (1):
      win32: replace pthread_cond_*() with much simpler code

Lucas De Marchi (1):
      range-diff: allow to diff files regardless of submodule config

Luke Diamand (3):
      git-p4: do not fail in verbose mode for missing 'fileSize' key
      git-p4: unshelve into refs/remotes/p4-unshelved, not refs/remotes/p4/unshelved
      git-p4: fully support unshelving changelists

Martin Ågren (11):
      Doc: use `--type=bool` instead of `--bool`
      git-config.txt: fix 'see: above' note
      git-commit-graph.txt: fix bullet lists
      git-commit-graph.txt: typeset more in monospace
      git-commit-graph.txt: refer to "*commit*-graph file"
      Doc: refer to the "commit-graph file" with dash
      t1400: drop debug `echo` to actually execute `test`
      builtin/commit-graph.c: UNLEAK variables
      sequencer: break out of loop explicitly
      git-reset.txt: render tables correctly under Asciidoctor
      git-reset.txt: render literal examples as monospace

Matthew DeVore (19):
      list-objects: store common func args in struct
      list-objects: refactor to process_tree_contents
      list-objects: always parse trees gently
      t/README: reformat Do, Don't, Keep in mind lists
      Documentation: add shell guidelines
      tests: standardize pipe placement
      t/*: fix ordering of expected/observed arguments
      tests: don't swallow Git errors upstream of pipes
      t9109: don't swallow Git errors upstream of pipes
      tests: order arguments to git-rev-list properly
      rev-list: handle missing tree objects properly
      revision: mark non-user-given objects instead
      list-objects-filter: use BUG rather than die
      list-objects-filter-options: do not over-strbuf_init
      list-objects-filter: implement filter tree:0
      filter-trees: code clean-up of tests
      list-objects: support for skipping tree traversal
      Documentation/git-log.txt: do not show --exclude-promisor-objects
      exclude-promisor-objects: declare when option is allowed

Max Kirillov (1):
      http-backend test: make empty CONTENT_LENGTH test more realistic

Michael Witten (3):
      docs: typo: s/go/to/
      docs: graph: remove unnecessary `graph_update()' call
      docs: typo: s/isimilar/similar/

Michał Górny (6):
      gpg-interface.c: detect and reject multiple signatures on commits
      gpg-interface.c: use flags to determine key/signer info presence
      gpg-interface.c: support getting key fingerprint via %GF format
      gpg-interface.c: obtain primary key fingerprint as well
      t/t7510-signed-commit.sh: Add %GP to custom format checks
      t/t7510-signed-commit.sh: add signing subkey to Eris Discordia key

Mihir Mehta (1):
      doc: fix a typo and clarify a sentence

Nguyễn Thái Ngọc Duy (170):
      clone: report duplicate entries on case-insensitive filesystems
      trace.h: support nested performance tracing
      unpack-trees: add performance tracing
      unpack-trees: optimize walking same trees with cache-tree
      unpack-trees: reduce malloc in cache-tree walk
      unpack-trees: reuse (still valid) cache-tree from src_index
      unpack-trees: add missing cache invalidation
      cache-tree: verify valid cache-tree in the test suite
      Document update for nd/unpack-trees-with-cache-tree
      bisect.c: make show_list() build again
      t/helper: keep test-tool command list sorted
      t/helper: merge test-dump-untracked-cache into test-tool
      t/helper: merge test-pkt-line into test-tool
      t/helper: merge test-parse-options into test-tool
      t/helper: merge test-dump-fsmonitor into test-tool
      Makefile: add a hint about TEST_BUILTINS_OBJS
      config.txt: follow camelCase naming
      config.txt: move fetch part out to a separate file
      config.txt: move format part out to a separate file
      config.txt: move gitcvs part out to a separate file
      config.txt: move gui part out to a separate file
      config.txt: move pull part out to a separate file
      config.txt: move push part out to a separate file
      config.txt: move receive part out to a separate file
      config.txt: move sendemail part out to a separate file
      config.txt: move sequence.editor out of "core" part
      config.txt: move submodule part out to a separate file
      archive.c: remove implicit dependency the_repository
      status: show progress bar if refreshing the index takes too long
      add: do not accept pathspec magic 'attr'
      completion: support "git fetch --multiple"
      read-cache.c: remove 'const' from index_has_changes()
      diff.c: reduce implicit dependency on the_index
      combine-diff.c: remove implicit dependency on the_index
      blame.c: rename "repo" argument to "r"
      diff.c: remove the_index dependency in textconv() functions
      grep.c: remove implicit dependency on the_index
      diff.c: remove implicit dependency on the_index
      read-cache.c: remove implicit dependency on the_index
      diff-lib.c: remove implicit dependency on the_index
      ll-merge.c: remove implicit dependency on the_index
      merge-blobs.c: remove implicit dependency on the_index
      merge.c: remove implicit dependency on the_index
      patch-ids.c: remove implicit dependency on the_index
      sha1-file.c: remove implicit dependency on the_index
      rerere.c: remove implicit dependency on the_index
      userdiff.c: remove implicit dependency on the_index
      line-range.c: remove implicit dependency on the_index
      submodule.c: remove implicit dependency on the_index
      tree-diff.c: remove implicit dependency on the_index
      ws.c: remove implicit dependency on the_index
      revision.c: remove implicit dependency on the_index
      revision.c: reduce implicit dependency the_repository
      read-cache.c: optimize reading index format v4
      config.txt: correct the note about uploadpack.packObjectsHook
      help -a: improve and make --verbose default
      refs.c: indent with tabs, not spaces
      Add a place for (not) sharing stuff between worktrees
      submodule.c: remove some of the_repository references
      completion: fix __gitcomp_builtin no longer consider extra options
      t1300: extract and use test_cmp_config()
      worktree: add per-worktree config files
      refs: new ref types to make per-worktree refs visible to all worktrees
      revision.c: correct a parameter name
      revision.c: better error reporting on ref from different worktrees
      fsck: check HEAD and reflog from other worktrees
      reflog expire: cover reflog from all worktrees
      Update makefile in preparation for Documentation/config/*.txt
      config.txt: move advice.* to a separate file
      config.txt: move core.* to a separate file
      config.txt: move add.* to a separate file
      config.txt: move alias.* to a separate file
      config.txt: move am.* to a separate file
      config.txt: move apply.* to a separate file
      config.txt: move blame.* to a separate file
      config.txt: move branch.* to a separate file
      config.txt: move browser.* to a separate file
      config.txt: move checkout.* to a separate file
      config.txt: move clean.* to a separate file
      config.txt: move color.* to a separate file
      config.txt: move column.* to a separate file
      config.txt: move commit.* to a separate file
      config.txt: move credential.* to a separate file
      config.txt: move completion.* to a separate file
      config.txt: move diff-config.txt to config/
      config.txt: move difftool.* to a separate file
      config.txt: move fastimport.* to a separate file
      config.txt: move fetch-config.txt to config/
      config.txt: move filter.* to a separate file
      config.txt: move format-config.txt to config/
      config.txt: move fmt-merge-msg-config.txt to config/
      config.txt: move fsck.* to a separate file
      config.txt: move gc.* to a separate file
      config.txt: move gitcvs-config.txt to config/
      config.txt: move gitweb.* to a separate file
      config.txt: move grep.* to a separate file
      config.txt: move gpg.* to a separate file
      config.txt: move gui-config.txt to config/
      config.txt: move guitool.* to a separate file
      config.txt: move help.* to a separate file
      config.txt: move ssh.* to a separate file
      config.txt: move http.* to a separate file
      config.txt: move i18n.* to a separate file
      git-imap-send.txt: move imap.* to a separate file
      config.txt: move index.* to a separate file
      config.txt: move init.* to a separate file
      config.txt: move instaweb.* to a separate file
      config.txt: move interactive.* to a separate file
      config.txt: move log.* to a separate file
      config.txt: move mailinfo.* to a separate file
      config.txt: move mailmap.* to a separate file
      config.txt: move man.* to a separate file
      config.txt: move merge-config.txt to config/
      config.txt: move mergetool.* to a separate file
      config.txt: move notes.* to a separate file
      config.txt: move pack.* to a separate file
      config.txt: move pager.* to a separate file
      config.txt: move pretty.* to a separate file
      config.txt: move protocol.* to a separate file
      config.txt: move pull-config.txt to config/
      config.txt: move push-config.txt to config/
      config.txt: move rebase-config.txt to config/
      config.txt: move receive-config.txt to config/
      config.txt: move remote.* to a separate file
      config.txt: move remotes.* to a separate file
      config.txt: move repack.* to a separate file
      config.txt: move rerere.* to a separate file
      config.txt: move reset.* to a separate file
      config.txt: move sendemail-config.txt to config/
      config.txt: move sequencer.* to a separate file
      config.txt: move showBranch.* to a separate file
      config.txt: move splitIndex.* to a separate file
      config.txt: move status.* to a separate file
      config.txt: move stash.* to a separate file
      config.txt: move submodule.* to a separate file
      config.txt: move tag.* to a separate file
      config.txt: move transfer.* to a separate file
      config.txt: move uploadarchive.* to a separate file
      config.txt: move uploadpack.* to a separate file
      config.txt: move url.* to a separate file
      config.txt: move user.* to a separate file
      config.txt: move versionsort.* to a separate file
      config.txt: move web.* to a separate file
      config.txt: move worktree.* to a separate file
      config.txt: remove config/dummy.txt
      thread-utils: macros to unconditionally compile pthreads API
      wildmatch: change behavior of "foo**bar" in WM_PATHNAME mode
      git-worktree.txt: correct linkgit command name
      sequencer.c: remove a stray semicolon
      tree-walk.c: fix overoptimistic inclusion in :(exclude) matching
      run-command.h: include thread-utils.h instead of pthread.h
      send-pack.c: move async's #ifdef NO_PTHREADS back to run-command.c
      index-pack: remove #ifdef NO_PTHREADS
      name-hash.c: remove #ifdef NO_PTHREADS
      attr.c: remove #ifdef NO_PTHREADS
      grep: remove #ifdef NO_PTHREADS
      grep: clean up num_threads handling
      preload-index.c: remove #ifdef NO_PTHREADS
      pack-objects: remove #ifdef NO_PTHREADS
      read-cache.c: remove #ifdef NO_PTHREADS
      read-cache.c: reduce branching based on HAVE_THREADS
      read-cache.c: initialize copy_len to shut up gcc 8
      Clean up pthread_create() error handling
      completion: use __gitcomp_builtin for format-patch
      build: fix broken command-list.h generation with core.autocrlf
      format-patch: respect --stat in cover letter's diffstat
      doc: move extensions.worktreeConfig to the right place
      clone: fix colliding file detection on APFS
      files-backend.c: fix build error on Solaris
      transport-helper.c: do not translate a string twice

Nickolai Belakovski (2):
      worktree: update documentation for lock_reason and lock_reason_valid
      worktree: rename is_worktree_locked to worktree_lock_reason

Noam Postavsky (1):
      log: fix coloring of certain octopus merge shapes

Olga Telezhnaya (3):
      ref-filter: free memory from used_atom
      ls-remote: release memory instead of UNLEAK
      ref-filter: free item->value and item->value->s

Phillip Wood (11):
      diff: fix --color-moved-ws=allow-indentation-change
      diff --color-moved-ws: fix double free crash
      diff --color-moved-ws: fix out of bounds string access
      diff --color-moved-ws: fix a memory leak
      diff --color-moved-ws: fix another memory leak
      diff --color-moved: fix a memory leak
      am: don't die in read_author_script()
      am: improve author-script error reporting
      am: rename read_author_script()
      add read_author_script() to libgit
      sequencer: use read_author_script()

Pratik Karki (46):
      rebase: start implementing it as a builtin
      rebase: refactor common shell functions into their own file
      builtin/rebase: support running "git rebase <upstream>"
      builtin rebase: support --onto
      builtin rebase: support `git rebase --onto A...B`
      builtin rebase: handle the pre-rebase hook and --no-verify
      builtin rebase: support --quiet
      builtin rebase: support the `verbose` and `diffstat` options
      builtin rebase: require a clean worktree
      builtin rebase: try to fast forward when possible
      builtin rebase: support --force-rebase
      builtin rebase: start a new rebase only if none is in progress
      builtin rebase: only store fully-qualified refs in `options.head_name`
      builtin rebase: support `git rebase <upstream> <switch-to>`
      builtin rebase: support --continue
      builtin rebase: support --skip
      builtin rebase: support --abort
      builtin rebase: support --quit
      builtin rebase: support --edit-todo and --show-current-patch
      builtin rebase: actions require a rebase in progress
      builtin rebase: stop if `git am` is in progress
      builtin rebase: allow selecting the rebase "backend"
      builtin rebase: support --signoff
      builtin rebase: support --rerere-autoupdate
      builtin rebase: support --committer-date-is-author-date
      builtin rebase: support `ignore-whitespace` option
      builtin rebase: support `ignore-date` option
      builtin rebase: support `keep-empty` option
      builtin rebase: support `--autosquash`
      builtin rebase: support `--gpg-sign` option
      builtin rebase: support `-C` and `--whitespace=<type>`
      builtin rebase: support `--autostash` option
      builtin rebase: support `--exec`
      builtin rebase: support `--allow-empty-message` option
      builtin rebase: support --rebase-merges[=[no-]rebase-cousins]
      merge-base --fork-point: extract libified function
      builtin rebase: support `fork-point` option
      builtin rebase: add support for custom merge strategies
      builtin rebase: support --root
      builtin rebase: optionally auto-detect the upstream
      builtin rebase: optionally pass custom reflogs to reset_head()
      builtin rebase: fast-forward to onto if it is a proper descendant
      builtin rebase: show progress when connected to a terminal
      builtin rebase: use no-op editor when interactive is "implied"
      builtin rebase: error out on incompatible option/mode combinations
      rebase: default to using the builtin rebase

Rafael Ascensão (2):
      refs: show --exclude failure with --branches/tags/remotes=glob
      refs: fix some exclude patterns being ignored

Ralf Thielow (2):
      git-rebase.sh: fix typos in error messages
      builtin/rebase.c: remove superfluous space in messages

Ramsay Jones (12):
      Makefile: add a hdr-check target
      json-writer.h: add missing include (hdr-check)
      ewah/ewok_rlw.h: add missing include (hdr-check)
      refs/ref-cache.h: add missing declarations (hdr-check)
      refs/packed-backend.h: add missing declaration (hdr-check)
      refs/refs-internal.h: add missing declarations (hdr-check)
      midx.h: add missing forward declarations (hdr-check)
      delta-islands.h: add missing forward declarations (hdr-check)
      headers: normalize the spelling of some header guards
      fetch-object.h: add missing declaration (hdr-check)
      ewok_rlw.h: add missing 'inline' to function definition
      commit-reach.h: add missing declarations (hdr-check)

Rasmus Villemoes (6):
      help: redirect to aliased commands for "git cmd --help"
      git.c: handle_alias: prepend alias info when first argument is -h
      git-help.txt: document "git help cmd" vs "git cmd --help" for aliases
      Documentation/git-send-email.txt: style fixes
      send-email: only consider lines containing @ or <> for automatic Cc'ing
      send-email: also pick up cc addresses from -by trailers

René Scharfe (12):
      mailinfo: support format=flowed
      fsck: add a performance test for skipList
      fsck: use strbuf_getline() to read skiplist file
      fsck: use oidset instead of oid_array for skipList
      sequencer: use return value of oidset_insert()
      grep: add -r/--[no-]recursive
      fetch-pack: factor out is_unmatched_ref()
      fetch-pack: load tip_oids eagerly iff needed
      khash: factor out kh_release_*
      oidset: use khash
      oidset: uninline oidset_init()
      commit-reach: fix cast in compare_commits_by_gen()

Roger Strain (1):
      subtree: performance improvement for finding unexpected parent commits

SZEDER Gábor (20):
      t1404: increase core.packedRefsTimeout to avoid occasional test failure
      Documentation/git.txt: clarify that GIT_TRACE=/path appends
      t3701-add-interactive: tighten the check of trace output
      t1700-split-index: drop unnecessary 'grep'
      t0090: disable GIT_TEST_SPLIT_INDEX for the test checking split index
      t1700-split-index: document why FSMONITOR is disabled in this test script
      split-index: add tests to demonstrate the racy split index problem
      t1700-split-index: date back files to avoid racy situations
      split-index: count the number of deleted entries
      split-index: don't compare cached data of entries already marked for split index
      split-index: smudge and add racily clean cache entries to split index
      split-index: BUG() when cache entry refers to non-existing shared entry
      object_id.cocci: match only expressions of type 'struct object_id'
      test-lib: introduce the '-V' short option for '--verbose-log'
      travis-ci: install packages in 'ci/install-dependencies.sh'
      coccicheck: introduce 'pending' semantic patches
      ref-filter: don't look for objects when outside of a repository
      tests: send "bug in the test script" errors to the script's stderr
      test-lib-functions: make 'test_cmp_rev' more informative on failure
      t/lib-git-daemon: fix signal checking

Sam McKelvie (1):
      rev-parse: --show-superproject-working-tree should work during a merge

Saulius Gurklys (1):
      doc: fix small typo in git show-branch

Sebastian Staudt (1):
      travis-ci: no longer use containers

Shulhan (1):
      builtin/remote: quote remote name on error to display empty name

Stefan Beller (25):
      git-submodule.sh: align error reporting for update mode to use path
      git-submodule.sh: rename unused variables
      builtin/submodule--helper: factor out submodule updating
      builtin/submodule--helper: store update_clone information in a struct
      builtin/submodule--helper: factor out method to update a single submodule
      submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree
      submodule--helper: introduce new update-module-mode helper
      test_decode_color: understand FAINT and ITALIC
      t3206: add color test for range-diff --dual-color
      diff.c: simplify caller of emit_line_0
      diff.c: reorder arguments for emit_line_ws_markup
      diff.c: add set_sign to emit_line_0
      diff: use emit_line_0 once per line
      diff.c: omit check for line prefix in emit_line_0
      diff.c: rewrite emit_line_0 more understandably
      diff.c: add --output-indicator-{new, old, context}
      range-diff: make use of different output indicators
      range-diff: indent special lines as context
      refs.c: migrate internal ref iteration to pass thru repository argument
      refs.c: upgrade for_each_replace_ref to be a each_repo_ref_fn callback
      string-list: remove unused function print_string_list
      strbuf.h: format according to coding guidelines
      diff.c: pass sign_index to emit_line_ws_markup
      submodule helper: convert relative URL to absolute URL if needed
      builtin/submodule--helper: remove debugging leftover tracing

Stephen P. Smith (10):
      wt-status.c: move has_unmerged earlier in the file
      wt-status: rename commitable to committable
      t7501: add test of "commit --dry-run --short"
      wt-status.c: set the committable flag in the collect phase
      roll wt_status_state into wt_status and populate in the collect phase
      t2000: rename and combine checkout clash tests
      t7509: cleanup description and filename
      t7502: rename commit test script to comply with naming convention
      t7500: rename commit tests script to comply with naming convention
      t7501: rename commit test to comply with naming convention

Steve Hoelzer (1):
      poll: use GetTickCount64() to avoid wrap-around issues

Steven Fernandez (1):
      git-completion.bash: add completion for stash list

Strain, Roger L (4):
      subtree: refactor split of a commit into standalone method
      subtree: make --ignore-joins pay attention to adds
      subtree: use commits before rejoins for splits
      subtree: improve decision on merges kept in split

Sven Strickroth (1):
      msvc: directly use MS version (_stricmp) of strcasecmp

Tao Qingyun (3):
      refs: docstring typo
      builtin/branch.c: remove useless branch_get
      branch: trivial style fix

Taylor Blau (4):
      transport.c: extract 'fill_alternate_refs_command'
      transport.c: introduce core.alternateRefsCommand
      transport.c: introduce core.alternateRefsPrefixes
      Documentation/config.txt: fix typo in core.alternateRefsCommand

Thomas Gummerer (17):
      rerere: unify error messages when read_cache fails
      rerere: lowercase error messages
      rerere: wrap paths in output in sq
      rerere: mark strings for translation
      rerere: add documentation for conflict normalization
      rerere: fix crash with files rerere can't handle
      rerere: only return whether a path has conflicts or not
      rerere: factor out handle_conflict function
      rerere: return strbuf from handle path
      rerere: teach rerere to handle nested conflicts
      rerere: recalculate conflict ID when unresolved conflict is committed
      rerere: mention caveat about unmatched conflict markers
      rerere: add note about files with existing conflict markers
      .gitattributes: add conflict-marker-size for relevant files
      linear-assignment: fix potential out of bounds memory access
      t5551: move setup code inside test_expect blocks
      t5551: compare sorted cookies files

Tim Schumacher (4):
      Documentation/Makefile: make manpage-base-url.xsl generation quieter
      alias: add support for aliases of an alias
      alias: show the call history when an alias is looping
      t0014: introduce an alias testing suite

Todd Zullinger (1):
      Documentation: build technical/multi-pack-index

Torsten Bögershausen (5):
      Make git_check_attr() a void function
      path.c: char is not (always) signed
      Upcast size_t variables to uintmax_t when printing
      remote-curl.c: xcurl_off_t is not portable (on 32 bit platfoms)
      t5601-99: Enable colliding file detection for MINGW

Uwe Kleine-König (1):
      howto/using-merge-subtree: mention --allow-unrelated-histories

brian m. carlson (26):
      t: add test functions to translate hash-related values
      t0000: use hash translation table
      t0000: update tests for SHA-256
      t0002: abstract away SHA-1 specific constants
      t0064: make hash size independent
      t1006: make hash size independent
      t1400: switch hard-coded object ID to variable
      t1405: make hash size independent
      t1406: make hash-size independent
      t1407: make hash size independent
      editorconfig: provide editor settings for Git developers
      editorconfig: indicate settings should be kept in sync
      pack-bitmap-write: use GIT_MAX_RAWSZ for allocation
      builtin/repack: replace hard-coded constants
      builtin/mktree: remove hard-coded constant
      builtin/fetch-pack: remove constants with parse_oid_hex
      pack-revindex: express constants in terms of the_hash_algo
      packfile: express constants in terms of the_hash_algo
      refs/packed-backend: express constants using the_hash_algo
      upload-pack: express constants in terms of the_hash_algo
      transport: use parse_oid_hex instead of a constant
      tag: express constant in terms of the_hash_algo
      apply: replace hard-coded constants
      apply: rename new_sha1_prefix and old_sha1_prefix
      submodule: make zero-oid comparison hash function agnostic
      rerere: convert to use the_hash_algo

Ævar Arnfjörð Bjarmason (35):
      fetch: change "branch" to "reference" in --force -h output
      push tests: make use of unused $1 in test description
      push tests: use spaces in interpolated string
      fetch tests: add a test for clobbering tag behavior
      push doc: remove confusing mention of remote merger
      push doc: move mention of "tag <tag>" later in the prose
      push doc: correct lies about how push refspecs work
      fetch: document local ref updates with/without --force
      fetch: stop clobbering existing tags without --force
      fsck tests: setup of bogus commit object
      fsck tests: add a test for no skipList input
      fsck: document and test sorted skipList input
      fsck: document and test commented & empty line skipList input
      fsck: document that skipList input must be unabbreviated
      fsck: add a performance test
      fsck: support comments & empty lines in skipList
      commit-graph write: add progress output
      commit-graph verify: add progress output
      config doc: add missing list separator for checkout.optimizeNewBranch
      push doc: add spacing between two words
      fetch doc: correct grammar in --force docs
      gc: fix regression in 7b0f229222 impacting --quiet
      gc doc: mention the commit-graph in the intro
      pack-objects test: modernize style
      pack-objects tests: don't leave test .git corrupt at end
      index-pack tests: don't leave test repo dirty at end
      i18n: make GETTEXT_POISON a runtime option
      range-diff doc: add a section about output stability
      range-diff: fix regression in passing along diff options
      range-diff: make diff option behavior (e.g. --stat) consistent
      push: change needlessly ambiguous example in error
      rebase doc: document rebase.useBuiltin
      tests: add a special setup where rebase.useBuiltin is off
      read-cache: make the split index obey umask settings
      advice: don't pointlessly suggest --convert-graft-file

Đoàn Trần Công Danh (1):
      git-compat-util: prefer poll.h to sys/poll.h


^ permalink raw reply

* [PATCH] Do not fail test if '.' is part of $PATH
From: H.Merijn Brand @ 2018-12-01 17:07 UTC (permalink / raw)
  To: git

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

When $PATH contains the current directory as .:PATH, PATH:., PATH:.:PATH,
or (maybe worse) as :PATH, PATH:, or PATH::PATH - as an empty entry is
identical to having dot in $PATH - this test used to fail

This patch was tested with PATH=$PATH, PATH=.:$PATH, PATH=$PATH:.,
PATH=$PATH:.:/bin, PATH=:$PATH, PATH=$PATH:, and PATH=$PATH::/bin

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Tested-by: H.Merijn Brand - Tux <h.m.brand@xs4all.nl>

diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh
index cf932c851..557f87442 100755
--- a/t/t0061-run-command.sh
+++ b/t/t0061-run-command.sh
@@ -29,7 +29,14 @@ test_expect_success 'run_command can run a command' '
        test_must_be_empty err
 '

-test_expect_success 'run_command is restricted to PATH' '
+test_lazy_prereq DOT_IN_PATH '
+       case ":$PATH:" in
+       *:.:*|*::*) true  ;;
+       *)          false ;;
+       esac
+'
+
+test_expect_success !DOT_IN_PATH 'run_command is restricted to PATH' '
        write_script should-not-run <<-\EOF &&
        echo yikes
        EOF

-- 
H.Merijn Brand  http://tux.nl   Perl Monger  http://amsterdam.pm.org/
using perl5.00307 .. 5.29   porting perl5 on HP-UX, AIX, and openSUSE
http://mirrors.develooper.com/hpux/        http://www.test-smoke.org/
http://qa.perl.org   http://www.goldmark.org/jeff/stupid-disclaimers/

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply related

* Re: [PATCH] t6036: avoid "cp -a"
From: Carlo Marcelo Arenas Belón @ 2018-12-01 17:36 UTC (permalink / raw)
  To: git; +Cc: gitster, newren
In-Reply-To: <xmqqk1ktjvyr.fsf@gitster-ct.c.googlers.com>

Thanks both. Agree with Junio it would be better if squashed; apologize
for not catching it earlier, but the following might help to make it
visible for anyone that care to run the linter:

  $ make test-lint-shell-syntax

Carlo
-- >8 --
From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= <carenas@gmail.com>
Subject: [PATCH] tests: add lint for non portable cp -a

cp -a, while a common flag isn't in POSIX and will therefore fail
on systems that don't have GNUish tools (like OpenBSD, AIX or Solaris)

Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
---
 t/check-non-portable-shell.pl | 1 +
 1 file changed, 1 insertion(+)

diff --git a/t/check-non-portable-shell.pl b/t/check-non-portable-shell.pl
index b45bdac688..8037eef777 100755
--- a/t/check-non-portable-shell.pl
+++ b/t/check-non-portable-shell.pl
@@ -35,6 +35,7 @@ sub err {
 		chomp;
 	}
 
+	/\bcp\s+-a/ and err 'cp -a is not portable';
 	/\bsed\s+-i/ and err 'sed -i is not portable';
 	/\becho\s+-[neE]/ and err 'echo with option is not portable (use printf)';
 	/^\s*declare\s+/ and err 'arrays/declare not portable';
-- 
2.20.0.rc2


^ permalink raw reply related

* Re: [PATCH] Do not fail test if '.' is part of $PATH
From: Jeff King @ 2018-12-01 19:38 UTC (permalink / raw)
  To: H.Merijn Brand; +Cc: git
In-Reply-To: <20181201180757.0b2d3c89@pc09.procura.nl>

On Sat, Dec 01, 2018 at 06:07:57PM +0100, H.Merijn Brand wrote:

> When $PATH contains the current directory as .:PATH, PATH:., PATH:.:PATH,
> or (maybe worse) as :PATH, PATH:, or PATH::PATH - as an empty entry is
> identical to having dot in $PATH - this test used to fail

Good catch. The test cares about Git not accidentally adding "." to the
PATH, but we can't check that if it is already there.

> This patch was tested with PATH=$PATH, PATH=.:$PATH, PATH=$PATH:.,
> PATH=$PATH:.:/bin, PATH=:$PATH, PATH=$PATH:, and PATH=$PATH::/bin
> [...]
> +test_lazy_prereq DOT_IN_PATH '
> +       case ":$PATH:" in
> +       *:.:*|*::*) true  ;;
> +       *)          false ;;
> +       esac
> +'

Since the test is ultimately checking "can we run should-not-run from
the current directory", might it be simpler to actually try that as the
precondition? I.e., something like:

  test_expect_success 'create program in current directory' '
	write_script should-not-run <<-\EOF &&
	echo yikes
	EOF
  '

  test_lazy_prereq DOT_IN_PATH '
	should-not-run
  '

  test_expect_success !DOT_IN_PATH 'run_command is restricted to PATH' '
	test_must_fail test-tool run-command run-command should-not-run
  '

?

That's more lines, but we don't have to peek into the details of how
$PATH works.

-Peff

^ permalink raw reply

* Re: [RFC 2/2] exclude-promisor-objects: declare when option is allowed
From: Jeff King @ 2018-12-01 19:44 UTC (permalink / raw)
  To: Matthew DeVore
  Cc: Matthew DeVore, git, gitster, pclouds, jonathantanmy, jeffhost
In-Reply-To: <19c82fb0-e0d6-0b15-06ab-cfba4d699d94@comcast.net>

On Fri, Nov 30, 2018 at 05:32:47PM -0800, Matthew DeVore wrote:

> > Speaking of which, would this flag work better as a field in
> > setup_revision_opt, which is passed to setup_revisions()? The intent
> > seem to be to influence how we parse command-line arguments, and that's
> > where other similar flags are (e.g., assume_dashdash).
> 
> Good idea. This would solve the problem of mistakenly believing the flag
> matters when it doesn't, since it is in the struct which is used as the
> arguments of the exact function that cares about it. Here's a new patch -
> I'm tweaking e-mail client settings so hopefully this makes it to the list
> without mangling - if not I'll resend it with `git-send-email` later.
> 
> From 941c89fe1e226ed4d210ce35d0d906526b8277ed Mon Sep 17 00:00:00 2001
> From: Matthew DeVore <matvore@google.com>
> Date: Fri, 30 Nov 2018 16:43:32 -0800
> Subject: [PATCH] revisions.c: put promisor option in specialized struct
> 
> Put the allow_exclude_promisor_objects flag in setup_revision_opt. When
> it was in rev_info, it was unclear when it was used, since rev_info is
> passed to functions that don't use the flag. This resulted in
> unnecessary setting of the flag in prune.c, so fix that as well.

Thanks, this looks pretty reasonable overall. Two comments:

>  	repo_init_revisions(the_repository, &revs, NULL);
>  	save_commit_buffer = 0;
> -	revs.allow_exclude_promisor_objects_opt = 1;
> -	setup_revisions(ac, av, &revs, NULL);
> +
> +	memset(&s_r_opt, 0, sizeof(s_r_opt));
> +	s_r_opt.allow_exclude_promisor_objects = 1;
> +	setup_revisions(ac, av, &revs, &s_r_opt);

I wonder if a static initializer for setup_revision_opt is worth it. It
would remove the need for this memset. Probably not a big deal either
way, though.

>  static int handle_revision_opt(struct rev_info *revs, int argc, const char
> **argv,
> -			       int *unkc, const char **unkv)
> +			       int *unkc, const char **unkv,
> +			       int allow_exclude_promisor_objects)

Why not pass in the whole setup_revision_opt struct? We don't need
anything else from it yet, but it seems like the point of that struct is
to pass around preferences like this.

-Peff

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox