Re: [PATCH v2 0/7] nd/worktree-move reboot
On Mon, Feb 12, 2018 at 4:49 AM, Nguyễn Thái Ngọc Duywrote: > v2 basically fixes lots of comments from Eric (many thanks!): memory > leak, typos, document updates, tests, corner case fixes. > Interdiff: Thanks, I finally got around to doing a full re-read of the entire series. v2 appears to address all issues raised in my review[1] of v1. I did find a few minor issues in tests newly added and revised in v2. However, since v2 already migrated to 'next', rather than pointing out the issues as review comments, I instead sent a patch[2] (built atop nd/worktree-move-reboot) to address them. [1]: https://public-inbox.org/git/20180124095357.19645-1-pclo...@gmail.com/ [2]: https://public-inbox.org/git/20180304052647.26614-1-sunsh...@sunshineco.com/
[PATCH] t2028: fix minor error and issues in newly-added "worktree move" tests
Recently-added "git worktree move" tests include a minor error and a few small issues. Specifically: * checking non-existence of wrong file ("source" instead of "destination") * unneeded redirect (">empty") * unused variable ("toplevel") * restoring a worktree location by means of a separate test somewhat distant from the test which moved it rather than using test_when_finished() to restore it in a self-contained fashion Signed-off-by: Eric Sunshine--- This patch is built atop nd/worktree-move-reboot in 'next'. I didn't get around to doing a proper review of nd/worktree-move-reboot v2 [1] until after it had graduated to 'next'. Although v2 fixed all the issues identified in my review of v1 [2], it introduced a few minor issues of its own. This patch addresses those issues. [1]: https://public-inbox.org/git/20180212094940.23834-1-pclo...@gmail.com/ [2]: https://public-inbox.org/git/20180124095357.19645-1-pclo...@gmail.com/ t/t2028-worktree-move.sh | 10 +++--- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/t/t2028-worktree-move.sh b/t/t2028-worktree-move.sh index 082368d8c6..d70d13dabe 100755 --- a/t/t2028-worktree-move.sh +++ b/t/t2028-worktree-move.sh @@ -75,7 +75,7 @@ test_expect_success 'move worktree' ' git worktree move source destination && test_path_is_missing source && git worktree list --porcelain | grep "^worktree.*/destination" && - ! git worktree list --porcelain | grep "^worktree.*/source" >empty && + ! git worktree list --porcelain | grep "^worktree.*/source" && git -C destination log --format=%s >actual2 && echo init >expected2 && test_cmp expected2 actual2 @@ -86,10 +86,10 @@ test_expect_success 'move main worktree' ' ' test_expect_success 'move worktree to another dir' ' - toplevel="$(pwd)" && mkdir some-dir && git worktree move destination some-dir && - test_path_is_missing source && + test_when_finished "git worktree move some-dir/destination destination" && + test_path_is_missing destination && git worktree list --porcelain | grep "^worktree.*/some-dir/destination" && git -C some-dir/destination log --format=%s >actual2 && echo init >expected2 && @@ -100,10 +100,6 @@ test_expect_success 'remove main worktree' ' test_must_fail git worktree remove . ' -test_expect_success 'move some-dir/destination back' ' - git worktree move some-dir/destination destination -' - test_expect_success 'remove locked worktree' ' git worktree lock destination && test_when_finished "git worktree unlock destination" && -- 2.16.2.660.g709887971b
Re: [PATCH] git.el: handle default excludesfile properly
On Sat, Mar 3, 2018 at 9:57 PM, Dorab Patelwrote: > Thanks for reviewing and locating the commits. > > OK, I'll re-roll and add the relevant commits. It may take some time. > > Should I just send the revised patch as a separate thread (with the > relevant commits and history)? That would work. You can use "git format-patch -v2 ..." to mark the patch as "[PATCH v2]", and "git send-email --in-reply-to=20180303034803.21589-1-dorabpa...@gmail.com ..." to tie it back to this thread when you send it. As a an aid to reviewers, it's a good idea to add commentary explaining what changed since v1 and provide a link back to v1, like this[1]. Place the commentary below the "---" line following your sign-off. (One more minor comment: etiquette on this list is to avoid top-posting [2].) Thanks. [1]: https://public-inbox.org/git/20180303034803.21589-1-dorabpa...@gmail.com/ [2]: https://lkml.org/lkml/2005/1/11/111
Re: [PATCH 13/44] pack: move approximate object count to object store
On Sun, Mar 4, 2018 at 9:47 AM, Eric Sunshinewrote: > On Sat, Mar 3, 2018 at 6:36 AM, Nguyễn Thái Ngọc Duy > wrote: >> The approximate_object_count() function maintains a rough count of >> objects in a repository to estimate how long object name abbreviates >> should be. Object names are scoped to a repository and the >> appropriate length may differ by repository, so the object count >> should not be global. >> >> Signed-off-by: Stefan Beller >> Signed-off-by: Jonathan Nieder >> Signed-off-by: Nguyễn Thái Ngọc Duy >> --- >> diff --git a/packfile.c b/packfile.c >> @@ -813,8 +811,8 @@ static int approximate_object_count_valid; >> unsigned long approximate_object_count(void) >> { >> - static unsigned long count; >> - if (!approximate_object_count_valid) { >> + if (!the_repository->objects.approximate_object_count_valid) { >> + unsigned long count; >> struct packed_git *p; >> >> prepare_packed_git(); >> @@ -824,8 +822,9 @@ unsigned long approximate_object_count(void) >> continue; >> count += p->num_objects; >> } >> + the_repository->objects.approximate_object_count = count; >> } >> - return count; >> + return the_repository->objects.approximate_object_count; >> } >> @@ -900,7 +899,7 @@ void prepare_packed_git(void) >> void reprepare_packed_git(void) >> { >> - approximate_object_count_valid = 0; >> + the_repository->objects.approximate_object_count_valid = 0; > > Not an issue specific to this patch, but where, how, when does > 'approximate_object_count_valid' ever get set to anything other than > 0? Even in the existing code (without this patch), there doesn't seem > to be anyplace which sets this to a non-zero value. Am I missing > something obvious (or subtle)? Probably related to this https://public-inbox.org/git/20180226085508.ga30...@sigill.intra.peff.net/#t -- Duy
Re: [PATCH 37/44] packfile: add repository argument to prepare_packed_git
On Sat, Mar 3, 2018 at 6:36 AM, Nguyễn Thái Ngọc Duywrote: > Add a repository argument to allow prepare_packed_git callers to > be more specific about which repository to handle. See c28d027a52c > (sha1_file: add repository argument to link_alt_odb_entry, 2018-02-20) > for an explanation of the #define trick. Object c28d027a52c doesn't exist. Most likely it was a reference to a change existing only in 'pu' which got replaced by a later revision of the series. > Signed-off-by: Stefan Beller > Signed-off-by: Nguyễn Thái Ngọc Duy
Re: [PATCH] git.el: handle default excludesfile properly
Thanks for reviewing and locating the commits. OK, I'll re-roll and add the relevant commits. It may take some time. Should I just send the revised patch as a separate thread (with the relevant commits and history)? On Sat, Mar 3, 2018 at 6:12 PM, Eric Sunshinewrote: > On Sat, Mar 3, 2018 at 8:36 PM, Dorab Patel wrote: >> Correct me if I'm wrong, but my understanding, from >> https://git-scm.com/docs/gitignore, is that $HOME/.gitignore is used >> only if it is specified as the value of core.excludesfile in >> ~/.gitconfig. It is not used by default. If that is so, then the >> proposed (and original) code works. The changes I am proposing handle >> the default case, when core.excludesfile is not specified. > > You're right. I must have set core.excludesfile so long ago that I > forgot about it and assumed $HOME/.gitignore was consulted by default. > >> Looking deeper into how the function git-get-exclude-files is used, I >> see that it is only being called from git-run-ls-files-with-excludes. >> So, perhaps, a better (or additional) fix might be to add the >> parameter "--exclude-standard" in the call to git-run-ls-files from >> within git-run-ls-files-with-excludes. And remove the need for >> get-get-exclude-files altogether. Presumably, "--exclude-standard" >> handles the default case with/without XDG_CONFIG_HOME correctly. The >> question I'd have then is: why didn't the original author use that >> option? Either I'm missing something? Or the option was added later, >> after the original code was written? Or something else? > > Using --exclude-standard rather than --exclude-from and retiring > git-get-exclude-files() makes sense to me. > > As for why the original author didn't use --exclude-standard, project > history tells us that. In particular, git-get-exclude-files() was > implemented by 274e13e0e9 (git.el: Take into account the > core.excludesfile config option., 2007-07-31), whereas > --exclude-standard was introduced by 8e7b07c8a7 (git-ls-files: add > --exclude-standard, 2007-11-15), three and a half months later. > > If you do re-roll to use --exclude-standard, then it would be good for > your commit message to explain this history, citing the relevant > commits. > > Thanks.
Re: [PATCH 13/44] pack: move approximate object count to object store
On Sat, Mar 3, 2018 at 6:36 AM, Nguyễn Thái Ngọc Duywrote: > The approximate_object_count() function maintains a rough count of > objects in a repository to estimate how long object name abbreviates > should be. Object names are scoped to a repository and the > appropriate length may differ by repository, so the object count > should not be global. > > Signed-off-by: Stefan Beller > Signed-off-by: Jonathan Nieder > Signed-off-by: Nguyễn Thái Ngọc Duy > --- > diff --git a/packfile.c b/packfile.c > @@ -813,8 +811,8 @@ static int approximate_object_count_valid; > unsigned long approximate_object_count(void) > { > - static unsigned long count; > - if (!approximate_object_count_valid) { > + if (!the_repository->objects.approximate_object_count_valid) { > + unsigned long count; > struct packed_git *p; > > prepare_packed_git(); > @@ -824,8 +822,9 @@ unsigned long approximate_object_count(void) > continue; > count += p->num_objects; > } > + the_repository->objects.approximate_object_count = count; > } > - return count; > + return the_repository->objects.approximate_object_count; > } > @@ -900,7 +899,7 @@ void prepare_packed_git(void) > void reprepare_packed_git(void) > { > - approximate_object_count_valid = 0; > + the_repository->objects.approximate_object_count_valid = 0; Not an issue specific to this patch, but where, how, when does 'approximate_object_count_valid' ever get set to anything other than 0? Even in the existing code (without this patch), there doesn't seem to be anyplace which sets this to a non-zero value. Am I missing something obvious (or subtle)?
Re: [PATCH 09/44] object-store: free alt_odb_list
On Sat, Mar 3, 2018 at 6:36 AM, Nguyễn Thái Ngọc Duywrote: > Free the memory and reset alt_odb_{list, tail} to NULL. > > Signed-off-by: Stefan Beller > Signed-off-by: Nguyễn Thái Ngọc Duy > --- > diff --git a/object.c b/object.c > @@ -450,8 +450,26 @@ void raw_object_store_init(struct raw_object_store *o) > +static void free_alt_odb(struct alternate_object_database *alt) > +{ > + strbuf_release(>scratch); > + oid_array_clear(>loose_objects_cache); > +} This doesn't free the 'struct alternate_object_database' entry itself, right? Is that intentional? Isn't the idea that this should free the entries too? > +static void free_alt_odbs(struct raw_object_store *o) > +{ > + while (o->alt_odb_list) { > + free_alt_odb(o->alt_odb_list); > + o->alt_odb_list = o->alt_odb_list->next; > + } > +} Accessing an entry's 'next' member after invoking free_alt_odb() works because the entry itself hasn't been freed (as noted above). Is leaking the entries themselves intentional? > void raw_object_store_clear(struct raw_object_store *o) > { > FREE_AND_NULL(o->objectdir); > FREE_AND_NULL(o->alternate_db); > + > + free_alt_odbs(o); > + o->alt_odb_tail = NULL; > } The commit message talks about freeing memory and resetting alt_odb_list and alt_odb_tail, but this code only resets alt_odb_tail.
Re: [PATCH 06/44] repository: introduce raw object store field
On Sat, Mar 3, 2018 at 6:35 AM, Nguyễn Thái Ngọc Duywrote: > The raw object store field will contain any objects needed for > access to objects in a given repository. > > This patch introduces the raw object store and populates it with the > `objectdir`, which used to be part of the repository struct. > > As the struct gains members, we'll also populate the function to clear > the memory for these members. > > In a later we'll introduce a struct object_parser, that will complement s/In a later/Later,/ > the object parsing in a repository struct: The raw object parser is the > layer that will provide access to raw object content, while the higher > level object parser code will parse raw objects and keeps track of > parenthood and other object relationships using 'struct object'. > For now only add the lower level to the repository struct. > > Signed-off-by: Stefan Beller > Signed-off-by: Jonathan Nieder > Signed-off-by: Nguyễn Thái Ngọc Duy
Re: [PATCH] git.el: handle default excludesfile properly
On Sat, Mar 3, 2018 at 8:36 PM, Dorab Patelwrote: > Correct me if I'm wrong, but my understanding, from > https://git-scm.com/docs/gitignore, is that $HOME/.gitignore is used > only if it is specified as the value of core.excludesfile in > ~/.gitconfig. It is not used by default. If that is so, then the > proposed (and original) code works. The changes I am proposing handle > the default case, when core.excludesfile is not specified. You're right. I must have set core.excludesfile so long ago that I forgot about it and assumed $HOME/.gitignore was consulted by default. > Looking deeper into how the function git-get-exclude-files is used, I > see that it is only being called from git-run-ls-files-with-excludes. > So, perhaps, a better (or additional) fix might be to add the > parameter "--exclude-standard" in the call to git-run-ls-files from > within git-run-ls-files-with-excludes. And remove the need for > get-get-exclude-files altogether. Presumably, "--exclude-standard" > handles the default case with/without XDG_CONFIG_HOME correctly. The > question I'd have then is: why didn't the original author use that > option? Either I'm missing something? Or the option was added later, > after the original code was written? Or something else? Using --exclude-standard rather than --exclude-from and retiring git-get-exclude-files() makes sense to me. As for why the original author didn't use --exclude-standard, project history tells us that. In particular, git-get-exclude-files() was implemented by 274e13e0e9 (git.el: Take into account the core.excludesfile config option., 2007-07-31), whereas --exclude-standard was introduced by 8e7b07c8a7 (git-ls-files: add --exclude-standard, 2007-11-15), three and a half months later. If you do re-roll to use --exclude-standard, then it would be good for your commit message to explain this history, citing the relevant commits. Thanks.
Re: [PATCH] git.el: handle default excludesfile properly
[[Pardon the duplicate. I forgot to send via text/plain and the mailing list bounced it, so resending.]] Thanks for the feedback. Correct me if I'm wrong, but my understanding, from https://git-scm.com/docs/gitignore, is that $HOME/.gitignore is used only if it is specified as the value of core.excludesfile in ~/.gitconfig. It is not used by default. If that is so, then the proposed (and original) code works. The changes I am proposing handle the default case, when core.excludesfile is not specified. Looking deeper into how the function git-get-exclude-files is used, I see that it is only being called from git-run-ls-files-with-excludes. So, perhaps, a better (or additional) fix might be to add the parameter "--exclude-standard" in the call to git-run-ls-files from within git-run-ls-files-with-excludes. And remove the need for get-get-exclude-files altogether. Presumably, "--exclude-standard" handles the default case with/without XDG_CONFIG_HOME correctly. The question I'd have then is: why didn't the original author use that option? Either I'm missing something? Or the option was added later, after the original code was written? Or something else? Thoughts? On Sat, Mar 3, 2018 at 12:42 AM, Eric Sunshinewrote: > On Fri, Mar 2, 2018 at 10:48 PM, Dorab Patel wrote: >> The previous version only looked at core.excludesfile for locating the >> excludesfile. So, when core.excludesfile was not defined, it did not >> use the possible default locations. >> >> The current version uses either $XDG_CONFIG_HOME/git/ignore or >> $HOME/.config/git/ignore for the default excludesfile location >> depending on whether XDG_CONFIG_HOME is defined or not. As per the >> documentation of gitignore. > > Perhaps take $HOME/.gitignore into account too? > >> Signed-off-by: Dorab Patel
[PATCH v3 2/2] send-email: Support separate Reply-To address
In some projects contributions from groups are only accepted from a common group email address. But every individual may want to receive replies to her own personal address. That's what we have 'Reply-To' headers for in SMTP. So introduce an optional '--reply-to' command line option. This patch re-uses the $reply_to variable. This could break out-of-tree patches! Signed-off-by: Christian Ludwig--- Documentation/git-send-email.txt | 5 + contrib/completion/git-completion.bash | 2 +- git-send-email.perl| 18 +- t/t9001-send-email.sh | 2 ++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt index 8060ea35c..71ef97ba9 100644 --- a/Documentation/git-send-email.txt +++ b/Documentation/git-send-email.txt @@ -84,6 +84,11 @@ See the CONFIGURATION section for `sendemail.multiEdit`. the value of GIT_AUTHOR_IDENT, or GIT_COMMITTER_IDENT if that is not set, as returned by "git var -l". +--reply-to=:: + Specify the address where replies from recipients should go to. + Use this if replies to messages should go to another address than what + is specified with the --from parameter. + --in-reply-to=:: Make the first mail (or all the mails with `--no-thread`) appear as a reply to the given Message-Id, which avoids breaking threads to diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index c7d5c7af2..4805b92ba 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -2081,7 +2081,7 @@ _git_send_email () --compose --confirm= --dry-run --envelope-sender --from --identity --in-reply-to --no-chain-reply-to --no-signed-off-by-cc - --no-suppress-from --no-thread --quiet + --no-suppress-from --no-thread --quiet --reply-to --signed-off-by-cc --smtp-pass --smtp-server --smtp-server-port --smtp-encryption= --smtp-user --subject --suppress-cc= --suppress-from --thread --to diff --git a/git-send-email.perl b/git-send-email.perl index 9eb12b5ba..707ec9eb7 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -57,6 +57,7 @@ git send-email --dump-aliases --[no-]cc * Email Cc: --[no-]bcc* Email Bcc: --subject * Email "Subject:" +--reply-to* Email "Reply-To:" --in-reply-to * Email "In-Reply-To:" --[no-]xmailer * Add "X-Mailer:" header (default). --[no-]annotate* Review each patch that will be sent in an editor. @@ -167,7 +168,7 @@ my $re_encoded_word = qr/=\?($re_token)\?($re_token)\?($re_encoded_text)\?=/; # Variables we fill in automatically, or via prompting: my (@to,$no_to,@initial_to,@cc,$no_cc,@initial_cc,@bcclist,$no_bcc,@xh, - $initial_in_reply_to,$initial_subject,@files, + $initial_in_reply_to,$reply_to,$initial_subject,@files, $author,$sender,$smtp_authpass,$annotate,$use_xmailer,$compose,$time); my $envelope_sender; @@ -316,6 +317,7 @@ die __("--dump-aliases incompatible with other options\n") $rc = GetOptions( "sender|from=s" => \$sender, "in-reply-to=s" => \$initial_in_reply_to, + "reply-to=s" => \$reply_to, "subject=s" => \$initial_subject, "to=s" => \@initial_to, "to-cmd=s" => \$to_cmd, @@ -678,6 +680,7 @@ if ($compose) { my $tpl_sender = $sender || $repoauthor || $repocommitter || ''; my $tpl_subject = $initial_subject || ''; my $tpl_in_reply_to = $initial_in_reply_to || ''; + my $tpl_reply_to = $reply_to || ''; print $c < " if $initial_in_reply_to ne ''; } +if (defined $reply_to) { + $reply_to =~ s/^\s+|\s+$//g; + ($reply_to) = expand_aliases($reply_to);
git-send-email: Support for Reply-To
Hi, this is the third iteration of this series. There was a request to rebase the changes on the refactoring patch b6049542 ("send-email: extract email-parsing code into a subroutine", 2017-12-15). This is the result. The diffstat is the same compared to the last revision. It could be made smaller by sacrificing readibility and breaking the scheme introduced by the refactoring patch. But I do agree that send-email's readability could benefit from slicing it into handy functions. And the refactoring patch reduces the nesting of loops/conditionals. But it's your code, you decide. I can re-send a fixed-up v2 without the rebasing. So long, - Christian
[PATCH v3 1/2] send-email: Rename variable for clarity
The SMTP protocol has both, the 'Reply-To' and the 'In-Reply-To' header fields. We only use the latter. To avoid confusion, rename the variable for it. Signed-off-by: Christian Ludwig--- git-send-email.perl | 38 +++--- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/git-send-email.perl b/git-send-email.perl index d0dcc6d7f..9eb12b5ba 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -167,13 +167,13 @@ my $re_encoded_word = qr/=\?($re_token)\?($re_token)\?($re_encoded_text)\?=/; # Variables we fill in automatically, or via prompting: my (@to,$no_to,@initial_to,@cc,$no_cc,@initial_cc,@bcclist,$no_bcc,@xh, - $initial_reply_to,$initial_subject,@files, + $initial_in_reply_to,$initial_subject,@files, $author,$sender,$smtp_authpass,$annotate,$use_xmailer,$compose,$time); my $envelope_sender; # Example reply to: -#$initial_reply_to = ''; #<20050203173208.ga23...@foobar.com>'; +#$initial_in_reply_to = ''; #<20050203173208.ga23...@foobar.com>'; my $repo = eval { Git->repository() }; my @repo = $repo ? ($repo) : (); @@ -315,7 +315,7 @@ die __("--dump-aliases incompatible with other options\n") if !$help and $dump_aliases and @ARGV; $rc = GetOptions( "sender|from=s" => \$sender, -"in-reply-to=s" => \$initial_reply_to, +"in-reply-to=s" => \$initial_in_reply_to, "subject=s" => \$initial_subject, "to=s" => \@initial_to, "to-cmd=s" => \$to_cmd, @@ -677,7 +677,7 @@ if ($compose) { my $tpl_sender = $sender || $repoauthor || $repocommitter || ''; my $tpl_subject = $initial_subject || ''; - my $tpl_reply_to = $initial_reply_to || ''; + my $tpl_in_reply_to = $initial_in_reply_to || ''; print $c < "", valid_re => qr/\@.*\./, confirm_only => 1); } -if (defined $initial_reply_to) { - $initial_reply_to =~ s/^\s*?\s*$//; - $initial_reply_to = "<$initial_reply_to>" if $initial_reply_to ne ''; +if (defined $initial_in_reply_to) { + $initial_in_reply_to =~ s/^\s*?\s*$//; + $initial_in_reply_to = "<$initial_in_reply_to>" if $initial_in_reply_to ne ''; } if (!defined $smtp_server) { @@ -941,7 +941,7 @@ if ($compose && $compose > 0) { } # Variables we set as part of the loop over files -our ($message_id, %mail, $subject, $reply_to, $references, $message, +our ($message_id, %mail, $subject, $in_reply_to, $references, $message, $needs_confirm, $message_num, $ask_default); sub extract_valid_address { @@ -1350,9 +1350,9 @@ Message-Id: $message_id if ($use_xmailer) { $header .= "X-Mailer: git-send-email $gitversion\n"; } - if ($reply_to) { + if ($in_reply_to) { - $header .= "In-Reply-To: $reply_to\n"; + $header .= "In-Reply-To: $in_reply_to\n"; $header .= "References: $references\n"; } if (@xh) { @@ -1529,8 +1529,8 @@ EOF return 1; } -$reply_to = $initial_reply_to; -$references = $initial_reply_to || ''; +$in_reply_to = $initial_in_reply_to; +$references = $initial_in_reply_to || ''; $subject = $initial_subject; $message_num = 0; @@ -1740,9 +1740,9 @@ foreach my $t (@files) { # set up for the next message if ($thread && $message_was_sent && - ($chain_reply_to || !defined $reply_to || length($reply_to) == 0 || + ($chain_reply_to || !defined $in_reply_to || length($in_reply_to) == 0 || $message_num == 1)) { - $reply_to = $message_id; + $in_reply_to = $message_id; if (length $references > 0) {
[PATCH] git-gui: workaround ttk:style theme use
Tk 8.5.7, which is the latest version on Centos 6, does not support getting the current theme with [ttk::style theme use]. Use the existing workaround for this in all places. Signed-off-by: Clemens Buchacher--- git-gui/lib/themed.tcl | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/git-gui/lib/themed.tcl b/git-gui/lib/themed.tcl index 351a712..88b3119 100644 --- a/git-gui/lib/themed.tcl +++ b/git-gui/lib/themed.tcl @@ -1,6 +1,14 @@ # Functions for supporting the use of themed Tk widgets in git-gui. # Copyright (C) 2009 Pat Thoyts +proc ttk_get_current_theme {} { + # Handle either current Tk or older versions of 8.5 + if {[catch {set theme [ttk::style theme use]}]} { + set theme $::ttk::currentTheme + } + return $theme +} + proc InitTheme {} { # Create a color label style (bg can be overridden by widget option) ttk::style layout Color.TLabel { @@ -28,10 +36,7 @@ proc InitTheme {} { } } - # Handle either current Tk or older versions of 8.5 - if {[catch {set theme [ttk::style theme use]}]} { - set theme $::ttk::currentTheme - } + set theme [ttk_get_current_theme] if {[lsearch -exact {default alt classic clam} $theme] != -1} { # Simple override of standard ttk::entry to change the field @@ -248,7 +253,7 @@ proc tspinbox {w args} { proc ttext {w args} { global use_ttk if {$use_ttk} { - switch -- [ttk::style theme use] { + switch -- [ttk_get_current_theme] { "vista" - "xpnative" { lappend args -highlightthickness 0 -borderwidth 0 } -- 2.7.4
[GSoC][PATCH v3] Make options that expect object ids less chatty if id is invalid
Usually, the usage should be shown only if the user does not know what options are available. If the user specifies an invalid value, the user is already aware of the available options. In this case, there is no point in displaying the usage anymore. This patch applies to "git tag --contains", "git branch --contains", "git branch --points-at", "git for-each-ref --contains" and many more. Signed-off-by: Paul-Sebastian Ungureanu--- builtin/update-index.c| 2 + parse-options.c | 13 +++-- parse-options.h | 1 + t/t0040-parse-options.sh | 9 ++-- t/t3404-rebase-interactive.sh | 2 +- t/t3502-cherry-pick-merge.sh | 8 +-- t/tcontains.sh| 92 +++ 7 files changed, 111 insertions(+), 16 deletions(-) create mode 100755 t/tcontains.sh diff --git a/builtin/update-index.c b/builtin/update-index.c index 58d1c2d28..1c170 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -1060,6 +1060,8 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) switch (parseopt_state) { case PARSE_OPT_HELP: exit(129); + case PARSE_OPT_ERROR: + exit(1); case PARSE_OPT_NON_OPTION: case PARSE_OPT_DONE: { diff --git a/parse-options.c b/parse-options.c index d02eb8b01..eee401662 100644 --- a/parse-options.c +++ b/parse-options.c @@ -434,7 +434,6 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, const char * const usagestr[]) { int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP); - int err = 0; /* we must reset ->opt, unknown short option leave it dangling */ ctx->opt = NULL; @@ -459,7 +458,7 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, ctx->opt = arg + 1; switch (parse_short_opt(ctx, options)) { case -1: - goto show_usage_error; + return PARSE_OPT_ERROR; case -2: if (ctx->opt) check_typos(arg + 1, options); @@ -472,7 +471,7 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, while (ctx->opt) { switch (parse_short_opt(ctx, options)) { case -1: - goto show_usage_error; + return PARSE_OPT_ERROR; case -2: if (internal_help && *ctx->opt == 'h') goto show_usage; @@ -504,7 +503,7 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, goto show_usage; switch (parse_long_opt(ctx, arg + 2, options)) { case -1: - goto show_usage_error; + return PARSE_OPT_ERROR; case -2: goto unknown; } @@ -517,10 +516,8 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, } return PARSE_OPT_DONE; - show_usage_error: - err = 1; show_usage: - return usage_with_options_internal(ctx, usagestr, options, 0, err); + return usage_with_options_internal(ctx, usagestr, options, 0, 0); } int parse_options_end(struct parse_opt_ctx_t *ctx) @@ -543,6 +540,8 @@ int parse_options(int argc, const char **argv, const char *prefix, case PARSE_OPT_NON_OPTION: case PARSE_OPT_DONE: break; + case PARSE_OPT_ERROR: + exit(1); default: /* PARSE_OPT_UNKNOWN */ if (ctx.argv[0][1] == '-') { error("unknown option `%s'", ctx.argv[0] + 2); diff --git a/parse-options.h b/parse-options.h index af711227a..c77bb3b4f 100644 --- a/parse-options.h +++ b/parse-options.h @@ -188,6 +188,7 @@ enum { PARSE_OPT_HELP = -1, PARSE_OPT_DONE, PARSE_OPT_NON_OPTION, + PARSE_OPT_ERROR, PARSE_OPT_UNKNOWN }; diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index 0c2fc81d7..8af12e8a1 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -162,9 +162,9 @@ test_expect_success 'long options' ' ' test_expect_success 'missing required value' ' - test_expect_code 129 test-parse-options -s && - test_expect_code 129 test-parse-options --string && - test_expect_code 129 test-parse-options --file + test_expect_code 1 test-parse-options -s && + test_expect_code 1 test-parse-options --string && + test_expect_code 1 test-parse-options --file ' cat >expect <<\EOF @@ -214,7 +214,7 @@ test_expect_success 'unambiguously abbreviated option
RE
I am Mr.Sheng Li Hung, from china I got your information while search for a reliable person, I have a very profitable business proposition for you and i can assure you that you will not regret been part of this mutual beneficial transaction after completion. Kindly get back to me for more details on this email id: shengl...@hotmail.com Thanks Mr Sheng Li Hung
Re: [RFC] Contributing to Git (on Windows)
Hi Dscho, Johannes Schindelin wrote: >> Jonathan Niederwrites: >>> Dereck Stolee wrote: +Test Your Changes on Linux +-- + +It can be important to work directly on the [core Git codebase](https://github.com/git/git), +such as a recent commit into the `master` or `next` branch that has not been incorporated +into Git for Windows. Also, it can help to run functional and performance tests on your +code in Linux before submitting patches to the Linux-focused mailing list. >>> >>> I'm surprised at this advice. Does it actually come up? > > Yes. > > I personally set up the automated builds on Windows, Linux and macOS for > our team, and as a rule we always open an internal Pull Request on our > topic branches as we develop them, and you would probably not believe the > number of issues we caught before sending the patches to this list. Issues > including [nice list snipped] Thanks for explaining. I still am going to push back on the wording here, and here is why: 1. Approximately 1/2 of the differences you describe apply to Mac as well as Windows. The advice certainly does not apply on Mac. You might object: Mac readers would not be reading this text! But that is not how humans work: if project documentation (e.g. the CONTRIBUTING.md on GitHub!) says that the project is Linux-focused and if you don't test on Linux then you might as well not bother, then people are going to believe it. 2. It is not unusual for Linux users to make portability mistakes that are quickly pointed out on list. If anything, the advice to test on other platforms should apply to contributors on Linux even more. This happens especially often to new contributors, who sometimes use bashisms, etc that get quickly pointed out. 3. I do not *want* Git to be a Linux-focused project; I want the code to perform well on all popular platforms and for people not to be afraid to make it so. If the docs say that all we care about is Linux, then people are likely to be too scared to do the necessary and valuable work of making it work well on Mac, Windows, etc. The actual mix of contributors doesn't bear it out anyway: a large number of contributors are already on Mac or Windows. Fortunately this is pretty straightforward to fix in the doc: it could say something like "to the multi-platform focused mailing list", for example. [...] > To my chagrin, this idea of making most of the boring stuff (and I include > formatting in that category, but I am probably special in that respect) as > automatable, and as little of an issue for review as possible, leaving > most brain cycles to work on the correctness of the patches instead, did > not really receive a lot of traction on this mailing list. Huh? I'm confident that this is a pretty widely supported idea within the Git project. I get the feeling you must have misread something or misinterpreted a different response. [...] > No, this advice comes straight from my personal observation that the > reviewers on the Git mailing list are Linux-centric. Hopefully the clarifications and suggestions higher in this message help. If they don't, then I'm nervous about our ability to understand each other. [...] > Now, how reasonable do I think it is to ask those contributors to purchase > an Apple machine to test their patches on macOS (you cannot just download > an .iso nor would it be legal to run a macOS VM on anything but Apple > hardware)? You probably guessed my answer: not at all. Agreed, this is something that needs to be automated (and not via a CONTRIBUTING.md file). As a stopgap, having a section in the contribution instructions about testing using Windows's Linux subsystem is a valuable thing, and thanks for that; I never meant to imply otherwise. [...] > On Fri, 2 Mar 2018, Junio C Hamano wrote: >> In fact, portability issues in a patch originally written for a platform >> is rather quickly discovered if the original platform is more minor than >> the others, so while it is good advice to test your ware before you make >> it public, singling out the portability issues may not add much value. >> The fewer number of obvious bugs remaining, the fewer number of >> iterations it would take for a series to get in a good shape. [...] > For you, Junio, however, the task *now* is to put yourself into the shoes > of a Computer Science student in their 2nd year who wants to become an > Open Source contributor and is a little afraid to talk directly to "the > core committers", and quite scared what negative feedback they might > receive. > > "What if they say my code is not good enough?" Sure, though there is something implied in what is Junio is saying that is useful for such people. It is patience. It is the message that if you miss a portability bug, we won't be disappointed in you, and it in fact happens all the time to the best
Re: [RFC] Contributing to Git (on Windows)
Hi, On Fri, 2 Mar 2018, Junio C Hamano wrote: > Jonathan Niederwrites: > > >> +Test Your Changes on Linux > >> +-- > >> + > >> +It can be important to work directly on the [core Git > >> codebase](https://github.com/git/git), +such as a recent commit into > >> the `master` or `next` branch that has not been incorporated +into > >> Git for Windows. Also, it can help to run functional and performance > >> tests on your +code in Linux before submitting patches to the > >> Linux-focused mailing list. > > > > I'm surprised at this advice. Does it actually come up? Yes. I personally set up the automated builds on Windows, Linux and macOS for our team, and as a rule we always open an internal Pull Request on our topic branches as we develop them, and you would probably not believe the number of issues we caught before sending the patches to this list. Issues including - scripts not being marked executable (on Windows, we don't care, but you Linux folks do), - use of symbols that are only available on Windows, but that were not guarded by appropriate `#ifdef`s, - printf formats available only on Windows, - EOL_NATIVE differences, - differences between BSD and GNU tools, such as the white-space in the output of `wc`, the syntactic differences of `sed`'s `-i` option, different options of the `stat` utility to do the same thing, etc (granted, this would not be caught when only testing on Windows and Linux, as both development environments would only use the GNU variety) Of course, these builds also catch problems by setting DEVELOPER=1 which developers might have forgotten to specify when building locally (it really is too easy to forget). > > When I was on Mac I never worried about this, nor when I was on > > Windows. I commend your boldness. Of course, you are an old-timer. These instructions are intended for new-timers, even first-timers, who may very well be very scared of reviews criticizing them for, say, not marking a new test script as executable. If you ever spoke to potential contributors who decided not to contribute after all, and you dig a little deeper, you might get the same impression as I got: they are (rightfully) scared of receiving answers with tons of comments what they did wrong. Most contributors seem to prefer to be "criticized" by tools, preferably even during the build process, where they can fix things before anybody sees their patches. This is, for example, the reason why the cURL project has this really nice `lib/checksrc.pl` script that they recommend you run to verify that the code you wrote abides by a few of their source code conventions they have. Developers run it, see what is wrong, fix it, and no human judges them. They submit the code, and the discussions revolve about how to improve the patch to cover more cases or some such. For that same reason, namely to make it less harsh for new contributors, I also tried to set up an automated job that tries to reformat patches using `clang-format` (without forcing any contributor to try to set up a bleeding-edge CLang, which can get very involved, very quickly) and pushes an updated topic branch if changes were needed. Sadly, this job is broken because I seem to be unable to get the `apt-get` commands right to get CLang's nightly builds (this job runs on Linux). To my chagrin, this idea of making most of the boring stuff (and I include formatting in that category, but I am probably special in that respect) as automatable, and as little of an issue for review as possible, leaving most brain cycles to work on the correctness of the patches instead, did not really receive a lot of traction on this mailing list. We still have no satisfactory automated way to check contributors' patches against our (quite fuzzy) coding style. Until that happens, contributors will be constantly faced with reviews about overly long lines, about grammar issues, about commit messages missing Signed-off-by: lines, about commit messages that are too short, etc. Those are all comments that not exactly make contributors feel welcome. And that comments also distract from more interesting use of reviewers' time (such as suggesting helper functions or data structures that the contributor could use to simplify the patches). But one thing that we *can* recommend to contributors (in particular Windows-based ones) is to verify that their patches work also on Linux, so that they can avoid receiving comments about that class of avoidable issues. > > I'm personally happy to review patches that haven't been tested on > > Linux, though it's of course even nicer if the patch author mentions > > what platforms they've tested on. Jonathan, I don't want this to sound harsh... but... this contributors' guide cares a little more about the feelings of the contributors than yours? ;-) Seriously again, you might not mind pointing out that a newly-added test case is not marked executable. The emotional
Re: [RFC] Rebasing merges: a jorney to the ultimate solution(RoadClear)
On 02/03/2018 19:14, Igor Djordjevic wrote: > > > > It is interesting to think what it means to faithfully rebase a '-s > > > ours' merge. In your example the rebase does not introduce any new > > > changes into branch B that it doesn't introduce to branch A. Had it > > > added a fixup to branch B1 for example or if the topology was more > > > complex so that B ended up with some other changes that the rebase did > > > not introduce into A, then M' would contain those extra changes whereas > > > '--recreate-merges' with '-s ours' (once it supports it) would not. > > > > Unless the method of merging was stored, I don't think we *can* > > correctly automate resolving of "-s ours" because all we store is the > > resulting content, and we don't know how or why the user generated it > > as such. I believe the "correct" solution in any case would be to take > > the content we DO know and then ask the user to stop for amendments. > > I agree with Jake, and for the exact same reasons. > > That said, I`d like to see what mentioned '--recreate-merges' with > '-s ours' does (or would do, once it supports it), would you have a > pointer for me where to look at? > > But if that`s something yet to come, might be it`s still open for > discussion. I mean, even this topic started inside original > `--recreate-merges` one[1], and hopefully it can still bring > improvements there (sooner or later). > > [1] > https://public-inbox.org/git/cover.1516225925.git.johannes.schinde...@gmx.de/ Ok, I went through mentioned `--recreate-merges` topic again, and I think I see one crucial merge commit handling difference. In there, as it is at the moment, merge commits are really to be _recreated_... as the option name seems to imply ;) In terms of interactive rebasing, it actually comes from "todo list" becoming much more powerful, gaining ability to create (new) merges, which is wonderful from the aspect of history rewriting (what rebase is all about). But, I would argue it is a different concept from actually _rebasing_ existing merge commits, being what we`re discussing about here. Yes, you can use merge commit (re)creation to "rebase" existing merge commit so the end result is the same, being what `--recreate-merges` now does, but that only goes for some (uninteresting?) merge commits where not knowing the deeper context of how the merge commit is originally created is not important as no content is to be lost (due to missing that deeper and utterly unknown context). But as soon as you try to do that with more complex merge commits, like holding manual amendments and conflict resolutions, it doesn`t really work as expected - which I demonstrated in my original example script[1] in this topic, original merge commit amendment lost on rebase, and even worse - that happened silently. Now, not to get misinterpreted to pick sides in "(re)create" vs "rebase" merge commit discussion, I just think these two (should) have a different purpose, and actually having both inside interactive rebase is what we should be aiming for. And that`s what I think is important to understand before any further discussion - _(re)creating_ existing merge commits is not the same as _rebasing_ them, even though the former can sometimes be used to achieve the latter. Regards, Buga [1] https://public-inbox.org/git/bbe64321-4d3a-d3fe-8bb9-58b600fab...@gmail.com/
Re: git stash push -u always warns "pathspec '...' did not match any files"
On 03/03, Marc Strapetz wrote: > Reproducible in a test repository with following steps: > > $ touch untracked > $ git stash push -u -- untracked > Saved working directory and index state WIP on master: 0096475 init > fatal: pathspec 'untracked' did not match any files > error: unrecognized input > > The file is stashed correctly, though. > > Tested with Git 2.16.2 on Linux and Windows. Thanks for the bug report and the reproduction recipe. The following patch should fix it: --- >8 --- Subject: [PATCH] stash push: avoid printing errors Currently 'git stash push -u -- ' prints the following errors if only matches untracked files: fatal: pathspec 'untracked' did not match any files error: unrecognized input This is because we first clean up the untracked files using 'git clean ', and then use a command chain involving 'git add -u ' and 'git apply' to clear the changes to files that are in the index and were stashed. As the only includes untracked files that were already removed by 'git clean', the 'git add' call will barf, and so will 'git apply', as there are no changes that need to be applied. Fix this by making sure to only call this command chain if there are still files that match after the call to 'git clean'. Reported-by: Marc StrapetzSigned-off-by: Thomas Gummerer --- git-stash.sh | 2 +- t/t3903-stash.sh | 7 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/git-stash.sh b/git-stash.sh index fc8f8ae640..058ad0bed8 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -320,7 +320,7 @@ push_stash () { git clean --force --quiet -d $CLEAN_X_OPTION -- "$@" fi - if test $# != 0 + if test $# != 0 && git ls-files --error-unmatch -- "$@" >/dev/null 2>/dev/null then git add -u -- "$@" | git checkout-index -z --force --stdin diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index aefde7b172..506004aece 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -1096,4 +1096,11 @@ test_expect_success 'stash -- works with binary files' ' test_path_is_file subdir/untracked ' +test_expect_success 'stash -- doesnt print error' ' + >untracked && + git stash push -u -- untracked 2>actual&& + test_path_is_missing untracked && + test_line_count = 0 actual +' + test_done -- 2.16.2.395.g2e18187dfd
[PATCH v3 12/13] Makefile: add NO_PERL_CPAN_FALLBACKS knob
From: Todd ZullingerWe include some perl modules which are not part of the core perl install, as a convenience. This allows us to rely on those modules in our perl-based tools and scripts without requiring users to install the modules from CPAN or their operating system packages. Users whose operating system provides these modules and packagers of Git often don't want to ship or use these bundled modules. Allow these users to set NO_PERL_CPAN_FALLBACKS to avoid installing the bundled modules. Signed-off-by: Todd Zullinger Signed-off-by: Ævar Arnfjörð Bjarmason --- Makefile | 8 1 file changed, 8 insertions(+) diff --git a/Makefile b/Makefile index 026b9fb6d6..cbf0bc2344 100644 --- a/Makefile +++ b/Makefile @@ -296,6 +296,12 @@ all:: # # Define NO_PERL if you do not want Perl scripts or libraries at all. # +# Define NO_PERL_CPAN_FALLBACKS if you do not want to install bundled +# copies of CPAN modules that serve as a fallback in case the modules +# are not available on the system. This option is intended for +# distributions that want to use their packaged versions of Perl +# modules, instead of the fallbacks shipped with Git. +# # Define PYTHON_PATH to the path of your Python binary (often /usr/bin/python # but /usr/bin/python2.7 on some platforms). # @@ -2307,8 +2313,10 @@ LIB_CPAN_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN)) ifndef NO_PERL all:: $(LIB_PERL_GEN) +ifndef NO_PERL_CPAN_FALLBACKS all:: $(LIB_CPAN_GEN) endif +endif perl/build/lib/%.pm: perl/%.pm $(QUIET_GEN)mkdir -p $(dir $@) && \ -- 2.15.1.424.g9478a66081
[PATCH v3 09/13] perl: move CPAN loader wrappers to another namespace
Move the Git::Error and Git::Mail::Address wrappers to the Git::LoadCPAN::Loader::* namespace, e.g. Git::LoadCPAN::Error. That module will then either load Error from CPAN (if installed on the OS), or use Git::FromCPAN::Error. When I added the Error wrapper in 20d2a30f8f ("Makefile: replace perl/Makefile.PL with simple make rules", 2017-12-10) I didn't think about how confusing it would be to have these modules sitting in the same tree as our normal modules. Let's put these all into Git::{Load,From}CPAN::* to clearly distinguish them from the rest. This also makes things a bit less confusing since there was already a Git::Error namespace ever since 8b9150e3e3 ("Git.pm: Handle failed commands' output", 2006-06-24). Signed-off-by: Ævar Arnfjörð Bjarmason--- contrib/examples/git-difftool.perl | 2 +- git-send-email.perl | 4 ++-- perl/Git.pm | 2 +- perl/Git/{ => LoadCPAN}/Error.pm| 8 perl/Git/{ => LoadCPAN}/Mail/Address.pm | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) rename perl/Git/{ => LoadCPAN}/Error.pm (78%) rename perl/Git/{ => LoadCPAN}/Mail/Address.pm (69%) diff --git a/contrib/examples/git-difftool.perl b/contrib/examples/git-difftool.perl index fb0fd0b84b..b2ea80f9ed 100755 --- a/contrib/examples/git-difftool.perl +++ b/contrib/examples/git-difftool.perl @@ -13,7 +13,7 @@ use 5.008; use strict; use warnings; -use Git::Error qw(:try); +use Git::LoadCPAN::Error qw(:try); use File::Basename qw(dirname); use File::Copy; use File::Find; diff --git a/git-send-email.perl b/git-send-email.perl index d5a4826a1c..1ec22c5ef3 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -26,13 +26,13 @@ use Text::ParseWords; use Term::ANSIColor; use File::Temp qw/ tempdir tempfile /; use File::Spec::Functions qw(catdir catfile); -use Git::Error qw(:try); +use Git::LoadCPAN::Error qw(:try); use Cwd qw(abs_path cwd); use Git; use Git::I18N; -use Git::Mail::Address; use Net::Domain (); use Net::SMTP (); +use Git::LoadCPAN::Mail::Address; Getopt::Long::Configure qw/ pass_through /; diff --git a/perl/Git.pm b/perl/Git.pm index 151b0e7144..9f246c7988 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -104,7 +104,7 @@ increase notwithstanding). use Carp qw(carp croak); # but croak is bad - throw instead -use Git::Error qw(:try); +use Git::LoadCPAN::Error qw(:try); use Cwd qw(abs_path cwd); use IPC::Open2 qw(open2); use Fcntl qw(SEEK_SET SEEK_CUR); diff --git a/perl/Git/Error.pm b/perl/Git/LoadCPAN/Error.pm similarity index 78% rename from perl/Git/Error.pm rename to perl/Git/LoadCPAN/Error.pm index 09bbc97390..3513fe745b 100644 --- a/perl/Git/Error.pm +++ b/perl/Git/LoadCPAN/Error.pm @@ -1,11 +1,11 @@ -package Git::Error; +package Git::LoadCPAN::Error; use 5.008; use strict; use warnings; =head1 NAME -Git::Error - Wrapper for the L module, in case it's not installed +Git::LoadCPAN::Error - Wrapper for the L module, in case it's not installed =head1 DESCRIPTION @@ -26,13 +26,13 @@ sub import { } or do { my $error = $@ || "Zombie Error"; - my $Git_Error_pm_path = $INC{"Git/Error.pm"} || die "BUG: Should have our own path from %INC!"; + my $Git_Error_pm_path = $INC{"Git/LoadCPAN/Error.pm"} || die "BUG: Should have our own path from %INC!"; require File::Basename; my $Git_Error_pm_root = File::Basename::dirname($Git_Error_pm_path) || die "BUG: Can't figure out lib/Git dirname from '$Git_Error_pm_path'!"; require File::Spec; - my $Git_pm_FromCPAN_root = File::Spec->catdir($Git_Error_pm_root, 'FromCPAN'); + my $Git_pm_FromCPAN_root = File::Spec->catdir($Git_Error_pm_root, '..', 'FromCPAN'); die "BUG: '$Git_pm_FromCPAN_root' should be a directory!" unless -d $Git_pm_FromCPAN_root; local @INC = ($Git_pm_FromCPAN_root, @INC); diff --git a/perl/Git/Mail/Address.pm b/perl/Git/LoadCPAN/Mail/Address.pm similarity index 69% rename from perl/Git/Mail/Address.pm rename to perl/Git/LoadCPAN/Mail/Address.pm index 2ce3e84670..879c2f5cd1 100644 --- a/perl/Git/Mail/Address.pm +++ b/perl/Git/LoadCPAN/Mail/Address.pm @@ -1,11 +1,11 @@ -package Git::Mail::Address; +package Git::LoadCPAN::Mail::Address; use 5.008; use strict; use warnings; =head1 NAME -Git::Mail::Address - Wrapper for the L module, in case it's not installed +Git::LoadCPAN::Mail::Address - Wrapper for the L module, in case it's not installed =head1 DESCRIPTION -- 2.15.1.424.g9478a66081
[PATCH v3 07/13] perl: update our ancient copy of Error.pm
The Error.pm shipped with Git as a fallback if there was no Error.pm on the system was released in April 2006. There's been dozens of releases since then, the latest at August 7, 2017. Let's update to that. I don't know of anything we need from this new release or which this fixes. This change is simply a matter of keeping up with upstream. Before this users who'd install git via their package system would get an up-to-date Error.pm, but if it's installed from source they'd get one more than a decade old. This undoes a local hack we'd accumulated in 96bc4de85c ("Eliminate Scalar::Util usage from private-Error.pm", 2006-07-26), it's been redundant since my d48b284183 ("perl: bump the required Perl version to 5.8 from 5.6.[21]", 2010-09-24). This also undoes 3a51467b94 ("Typo fix: replacing it's -> its", 2013-04-13). This is the Nth time I find that some upstream code of ours (in contrib/, in sha1dc/ and now in perl/ ...) has diverged from upstream because of some tree-wide typo fixing. Let's not do those fixes against upstream projects, it's more valuable that we have a 1=1 mapping to upstream than to fix typos in docs we never even generate from this code. If someone wants to fix typos in them fine, but they should do it with a patch to upstream which git.git can then incorporate. The upstream code doesn't cleanly pass a --check, so I'm adding a .gitattributes file for similar reasons as done for sha1dc in 5d184f468e ("sha1dc: ignore indent-with-non-tab whitespace violations", 2017-06-06). The updated source was retrieved from https://fastapi.metacpan.org/source/SHLOMIF/Error-0.17025/lib/Error.pm Signed-off-by: Ævar Arnfjörð Bjarmason--- perl/Git/FromCPAN/.gitattributes | 1 + perl/Git/FromCPAN/Error.pm | 296 +-- 2 files changed, 256 insertions(+), 41 deletions(-) create mode 100644 perl/Git/FromCPAN/.gitattributes diff --git a/perl/Git/FromCPAN/.gitattributes b/perl/Git/FromCPAN/.gitattributes new file mode 100644 index 00..8b64fc5e22 --- /dev/null +++ b/perl/Git/FromCPAN/.gitattributes @@ -0,0 +1 @@ +/Error.pm whitespace=-blank-at-eof diff --git a/perl/Git/FromCPAN/Error.pm b/perl/Git/FromCPAN/Error.pm index 6098135ae2..f9c36e9e98 100644 --- a/perl/Git/FromCPAN/Error.pm +++ b/perl/Git/FromCPAN/Error.pm @@ -12,10 +12,12 @@ package Error; use strict; +use warnings; + use vars qw($VERSION); use 5.004; -$VERSION = "0.15009"; +$VERSION = "0.17025"; use overload ( '""' => 'stringify', @@ -32,21 +34,35 @@ $Error::THROWN = undef; # last error thrown, a workaround until die $ref works my $LAST; # Last error created my %ERROR; # Last error associated with package -sub throw_Error_Simple +sub _throw_Error_Simple { my $args = shift; return Error::Simple->new($args->{'text'}); } -$Error::ObjectifyCallback = \_Error_Simple; +$Error::ObjectifyCallback = \&_throw_Error_Simple; # Exported subs are defined in Error::subs +use Scalar::Util (); + sub import { shift; +my @tags = @_; local $Exporter::ExportLevel = $Exporter::ExportLevel + 1; -Error::subs->import(@_); + +@tags = grep { + if( $_ eq ':warndie' ) { + Error::WarnDie->import(); + 0; + } + else { + 1; + } +} @tags; + +Error::subs->import(@tags); } # I really want to use last for the name of this method, but it is a keyword @@ -107,10 +123,6 @@ sub stacktrace { $text; } -# Allow error propagation, ie -# -# $ber->encode(...) or -#return Error->prior($ber)->associate($ldap); sub associate { my $err = shift; @@ -130,6 +142,7 @@ sub associate { return; } + sub new { my $self = shift; my($pkg,$file,$line) = caller($Error::Depth); @@ -246,6 +259,10 @@ sub value { package Error::Simple; +use vars qw($VERSION); + +$VERSION = "0.17025"; + @Error::Simple::ISA = qw(Error); sub new { @@ -288,14 +305,6 @@ use vars qw(@EXPORT_OK @ISA %EXPORT_TAGS); @ISA = qw(Exporter); - -sub blessed { - my $item = shift; - local $@; # don't kill an outer $@ - ref $item and eval { $item->can('can') }; -} - - sub run_clauses ($$$\@) { my($clauses,$err,$wantarray,$result) = @_; my $code = undef; @@ -314,16 +323,17 @@ sub run_clauses ($$$\@) { my $pkg = $catch->[$i]; unless(defined $pkg) { #except - splice(@$catch,$i,2,$catch->[$i+1]->()); + splice(@$catch,$i,2,$catch->[$i+1]->($err)); $i -= 2; next CATCHLOOP; } - elsif(blessed($err) && $err->isa($pkg)) { + elsif(Scalar::Util::blessed($err) && $err->isa($pkg)) { $code = $catch->[$i+1]; while(1) { my $more = 0; - local($Error::THROWN); +
[PATCH v3 08/13] perl: update our copy of Mail::Address
Update our copy of Mail::Address from 2.19 (Aug 22, 2017) to 2.20 (Jan 23, 2018). Like the preceding Error.pm update this is done simply to keep up-to-date with upstream, and as can be shown from the diff there's no functional changes. The updated source was retrieved from https://fastapi.metacpan.org/source/MARKOV/MailTools-2.20/lib/Mail/Address.pm Signed-off-by: Ævar Arnfjörð Bjarmason--- perl/Git/FromCPAN/Mail/Address.pm | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/perl/Git/FromCPAN/Mail/Address.pm b/perl/Git/FromCPAN/Mail/Address.pm index 13b2ff7d05..683d490b2b 100644 --- a/perl/Git/FromCPAN/Mail/Address.pm +++ b/perl/Git/FromCPAN/Mail/Address.pm @@ -1,10 +1,14 @@ -# Copyrights 1995-2017 by [Mark Overmeer ]. +# Copyrights 1995-2018 by [Mark Overmeer]. # For other contributors see ChangeLog. # See the manual pages for details on the licensing terms. # Pod stripped from pm file by OODoc 2.02. +# This code is part of the bundle MailTools. Meta-POD processed with +# OODoc into POD and HTML manual-pages. See README.md for Copyright. +# Licensed under the same terms as Perl itself. + package Mail::Address; use vars '$VERSION'; -$VERSION = '2.19'; +$VERSION = '2.20'; use strict; -- 2.15.1.424.g9478a66081
[PATCH v3 10/13] perl: generalize the Git::LoadCPAN facility
Change the two wrappers that load from CPAN (local OS) or our own copy to do so via the same codepath. I added the Error.pm wrapper in 20d2a30f8f ("Makefile: replace perl/Makefile.PL with simple make rules", 2017-12-10), and shortly afterwards Matthieu Moy added a wrapper for Mail::Address in bd869f67b9 ("send-email: add and use a local copy of Mail::Address", 2018-01-05). His loader was simpler since Mail::Address doesn't have an "import" method, but didn't do the same sanity checking; For example, a missing FromCPAN directory (which OS packages are likely not to have) wouldn't be explicitly warned about as a "BUG: ...". Update both to use a common implementation based on the previous Error.pm loader. Which has been amended to take the module to load as parameter, as well as whether or not that module has an import method. This loader should be generic enough to handle almost all CPAN modules out there, some use some crazy loading magic and wouldn't like being wrapped like this, but that would be immediately obvious, and we'd find out right away since the module wouldn't work at all. Signed-off-by: Ævar Arnfjörð Bjarmason--- perl/Git/LoadCPAN.pm | 74 +++ perl/Git/LoadCPAN/Error.pm| 44 +++ perl/Git/LoadCPAN/Mail/Address.pm | 22 +++- 3 files changed, 82 insertions(+), 58 deletions(-) create mode 100644 perl/Git/LoadCPAN.pm diff --git a/perl/Git/LoadCPAN.pm b/perl/Git/LoadCPAN.pm new file mode 100644 index 00..1568c177fe --- /dev/null +++ b/perl/Git/LoadCPAN.pm @@ -0,0 +1,74 @@ +package Git::LoadCPAN; +use 5.008; +use strict; +use warnings; + +=head1 NAME + +Git::LoadCPAN - Wrapper for loading modules from the CPAN (OS) or Git's own copy + +=head1 DESCRIPTION + +The Perl code in Git depends on some modules from the CPAN, but we +don't want to make those a hard requirement for anyone building from +source. + +Therefore the L namespace shipped with Git contains +wrapper modules like C that will first +attempt to load C from the OS, and if that doesn't work +will fall back on C shipped with Git +itself. + +Usually distributors will not ship with Git's Git::FromCPAN tree at +all, preferring to use their own packaging of CPAN modules instead. + +This module is only intended to be used for code shipping in the +C repository. Use it for anything else at your peril! + +=cut + +sub import { + shift; + my $caller = caller; + my %args = @_; + my $module = exists $args{module} ? delete $args{module} : die "BUG: Expected 'module' parameter!"; + my $import = exists $args{import} ? delete $args{import} : die "BUG: Expected 'import' parameter!"; + die "BUG: Too many arguments!" if keys %args; + + # Foo::Bar to Foo/Bar.pm + my $package_pm = $module; + $package_pm =~ s[::][/]g; + $package_pm .= '.pm'; + + eval { + require $package_pm; + 1; + } or do { + my $error = $@ || "Zombie Error"; + + my $Git_LoadCPAN_pm_path = $INC{"Git/LoadCPAN.pm"} || die "BUG: Should have our own path from %INC!"; + + require File::Basename; + my $Git_LoadCPAN_pm_root = File::Basename::dirname($Git_LoadCPAN_pm_path) || die "BUG: Can't figure out lib/Git dirname from '$Git_LoadCPAN_pm_path'!"; + + require File::Spec; + my $Git_pm_FromCPAN_root = File::Spec->catdir($Git_LoadCPAN_pm_root, 'FromCPAN'); + die "BUG: '$Git_pm_FromCPAN_root' should be a directory!" unless -d $Git_pm_FromCPAN_root; + + local @INC = ($Git_pm_FromCPAN_root, @INC); + require $package_pm; + }; + + if ($import) { + no strict 'refs'; + *{"${caller}::import"} = sub { + shift; + use strict 'refs'; + unshift @_, $module; + goto &{"${module}::import"}; + }; + use strict 'refs'; + } +} + +1; diff --git a/perl/Git/LoadCPAN/Error.pm b/perl/Git/LoadCPAN/Error.pm index 3513fe745b..c6d2c45d80 100644 --- a/perl/Git/LoadCPAN/Error.pm +++ b/perl/Git/LoadCPAN/Error.pm @@ -2,45 +2,9 @@ package Git::LoadCPAN::Error; use 5.008; use strict; use warnings; - -=head1 NAME - -Git::LoadCPAN::Error - Wrapper for the L module, in case it's not installed - -=head1 DESCRIPTION - -Wraps the import function for the L module. - -This module is only intended to be used for code shipping in the -C repository. Use it for anything else at your peril! - -=cut - -sub import { -shift; -my $caller = caller; - -eval { - require Error; - 1; -} or do { - my $error = $@ || "Zombie Error"; - - my $Git_Error_pm_path = $INC{"Git/LoadCPAN/Error.pm"} || die "BUG: Should have our own path from %INC!"; - - require File::Basename; - my $Git_Error_pm_root =
[PATCH v3 13/13] perl Git::LoadCPAN: emit better errors under NO_PERL_CPAN_FALLBACKS
Before my 20d2a30f8f ("Makefile: replace perl/Makefile.PL with simple make rules", 2017-12-10) on an OS package that removed the private-Error.pm copy we carried around manually removing the OS's Error.pm would yield: $ git add -p Can't locate Error.pm in @INC (you may need to install the Error module) [...] Now, before this change we'll instead emit this more cryptic error: $ git add -p BUG: '/usr/share/perl5/Git/FromCPAN' should be a directory! at /usr/share/perl5/Git/Error.pm line 36. This is a confusing error. Now if the new NO_PERL_CPAN_FALLBACKS option is specified and we can't find the module we'll instead emit: $ /tmp/git/bin/git add -p BUG: The 'Error' module is not here, but NO_PERL_CPAN_FALLBACKS was set! [...] Where [...] is the lengthy explanation seen in the change below, which explains what the potential breakage is, and how to fix it. The reason for checking @@NO_PERL_CPAN_FALLBACKS@@] against the empty string in Perl is as opposed to checking for a boolean value is that that's (as far as I can tell) make's idea of a string that's set, and e.g. NO_PERL_CPAN_FALLBACKS=0 is enough to set NO_PERL_CPAN_FALLBACKS. Signed-off-by: Ævar Arnfjörð Bjarmason--- INSTALL | 11 --- Makefile | 5 - perl/Git/LoadCPAN.pm | 33 - 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/INSTALL b/INSTALL index 808e07b659..60e515eaf7 100644 --- a/INSTALL +++ b/INSTALL @@ -88,9 +88,9 @@ Issues of note: export GIT_EXEC_PATH PATH GITPERLLIB - By default (unless NO_PERL is provided) Git will ship various perl - scripts & libraries it needs. However, for simplicity it doesn't - use the ExtUtils::MakeMaker toolchain to decide where to place the - perl libraries. Depending on the system this can result in the perl + scripts. However, for simplicity it doesn't use the + ExtUtils::MakeMaker toolchain to decide where to place the perl + libraries. Depending on the system this can result in the perl libraries not being where you'd like them if they're expected to be used by things other than Git itself. @@ -102,6 +102,11 @@ Issues of note: Will result in e.g. perllibdir=/usr/share/perl/5.26.1 on Debian, perllibdir=/usr/share/perl5 (which we'd use by default) on CentOS. + - Unless NO_PERL is provided Git will ship various perl libraries it + needs. Distributors of Git will usually want to set + NO_PERL_CPAN_FALLBACKS if NO_PERL is not provided to use their own + copies of the CPAN modules Git needs. + - Git is reasonably self-sufficient, but does depend on a few external programs and libraries. Git can be used without most of them by adding the approriate "NO_=YesPlease" to the make command line or diff --git a/Makefile b/Makefile index cbf0bc2344..56fc2d6f08 100644 --- a/Makefile +++ b/Makefile @@ -2316,11 +2316,14 @@ all:: $(LIB_PERL_GEN) ifndef NO_PERL_CPAN_FALLBACKS all:: $(LIB_CPAN_GEN) endif +NO_PERL_CPAN_FALLBACKS_SQ = $(subst ','\'',$(NO_PERL_CPAN_FALLBACKS)) endif perl/build/lib/%.pm: perl/%.pm $(QUIET_GEN)mkdir -p $(dir $@) && \ - sed -e 's|@@LOCALEDIR@@|$(localedir_SQ)|g' < $< > $@ + sed -e 's|@@LOCALEDIR@@|$(localedir_SQ)|g' \ + -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(NO_PERL_CPAN_FALLBACKS_SQ)|g' \ + < $< > $@ perl/build/man/man3/Git.3pm: perl/Git.pm $(QUIET_GEN)mkdir -p $(dir $@) && \ diff --git a/perl/Git/LoadCPAN.pm b/perl/Git/LoadCPAN.pm index 229c1ee87d..e5585e75e8 100644 --- a/perl/Git/LoadCPAN.pm +++ b/perl/Git/LoadCPAN.pm @@ -19,13 +19,25 @@ attempt to load C from the OS, and if that doesn't work will fall back on C shipped with Git itself. Usually distributors will not ship with Git's Git::FromCPAN tree at -all, preferring to use their own packaging of CPAN modules instead. +all via the C option, preferring to use their +own packaging of CPAN modules instead. This module is only intended to be used for code shipping in the C repository. Use it for anything else at your peril! =cut +# NO_PERL_CPAN_FALLBACKS_STR evades the sed search-replace from the +# Makefile, and allows for detecting whether the module is loaded from +# perl/Git as opposed to perl/build/Git, which is useful for one-off +# testing without having Error.pm et al installed. +use constant NO_PERL_CPAN_FALLBACKS_STR => '@@' . 'NO_PERL_CPAN_FALLBACKS' . '@@'; +use constant NO_PERL_CPAN_FALLBACKS => ( + q[@@NO_PERL_CPAN_FALLBACKS@@] ne '' + and + q[@@NO_PERL_CPAN_FALLBACKS@@] ne NO_PERL_CPAN_FALLBACKS_STR +); + sub import { shift; my $caller = caller; @@ -45,6 +57,25 @@ sub import { } or do { my $error = $@ || "Zombie Error"; + if (NO_PERL_CPAN_FALLBACKS) { + chomp(my $error = sprintf <<'THEY_PROMISED', $module); +BUG: The '%s' module is not here, but NO_PERL_CPAN_FALLBACKS was set! +
[PATCH v3 11/13] perl: move the perl/Git/FromCPAN tree to perl/FromCPAN
Move the CPAN modules that have lived under perl/Git/FromCPAN since my 20d2a30f8f ("Makefile: replace perl/Makefile.PL with simple make rules", 2017-12-10) to perl/FromCPAN. A subsequent change will teach the Makefile to only install these copies of CPAN modules if a flag that distro packagers would like to set isn't set. Due to how the wildcard globbing is being done it's much easier to accomplish that if they're moved to their own directory. Signed-off-by: Ævar Arnfjörð Bjarmason--- Makefile| 3 +++ perl/{Git => }/FromCPAN/.gitattributes | 0 perl/{Git => }/FromCPAN/Error.pm| 0 perl/{Git => }/FromCPAN/Mail/Address.pm | 0 perl/Git/LoadCPAN.pm| 5 ++--- 5 files changed, 5 insertions(+), 3 deletions(-) rename perl/{Git => }/FromCPAN/.gitattributes (100%) rename perl/{Git => }/FromCPAN/Error.pm (100%) rename perl/{Git => }/FromCPAN/Mail/Address.pm (100%) diff --git a/Makefile b/Makefile index 5ae9616e0a..026b9fb6d6 100644 --- a/Makefile +++ b/Makefile @@ -2302,9 +2302,12 @@ po/build/locale/%/LC_MESSAGES/git.mo: po/%.po LIB_PERL := $(wildcard perl/Git.pm perl/Git/*.pm perl/Git/*/*.pm perl/Git/*/*/*.pm) LIB_PERL_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_PERL)) +LIB_CPAN := $(wildcard perl/FromCPAN/*.pm perl/FromCPAN/*/*.pm) +LIB_CPAN_GEN := $(patsubst perl/%.pm,perl/build/lib/%.pm,$(LIB_CPAN)) ifndef NO_PERL all:: $(LIB_PERL_GEN) +all:: $(LIB_CPAN_GEN) endif perl/build/lib/%.pm: perl/%.pm diff --git a/perl/Git/FromCPAN/.gitattributes b/perl/FromCPAN/.gitattributes similarity index 100% rename from perl/Git/FromCPAN/.gitattributes rename to perl/FromCPAN/.gitattributes diff --git a/perl/Git/FromCPAN/Error.pm b/perl/FromCPAN/Error.pm similarity index 100% rename from perl/Git/FromCPAN/Error.pm rename to perl/FromCPAN/Error.pm diff --git a/perl/Git/FromCPAN/Mail/Address.pm b/perl/FromCPAN/Mail/Address.pm similarity index 100% rename from perl/Git/FromCPAN/Mail/Address.pm rename to perl/FromCPAN/Mail/Address.pm diff --git a/perl/Git/LoadCPAN.pm b/perl/Git/LoadCPAN.pm index 1568c177fe..229c1ee87d 100644 --- a/perl/Git/LoadCPAN.pm +++ b/perl/Git/LoadCPAN.pm @@ -16,8 +16,7 @@ source. Therefore the L namespace shipped with Git contains wrapper modules like C that will first attempt to load C from the OS, and if that doesn't work -will fall back on C shipped with Git -itself. +will fall back on C shipped with Git itself. Usually distributors will not ship with Git's Git::FromCPAN tree at all, preferring to use their own packaging of CPAN modules instead. @@ -52,7 +51,7 @@ sub import { my $Git_LoadCPAN_pm_root = File::Basename::dirname($Git_LoadCPAN_pm_path) || die "BUG: Can't figure out lib/Git dirname from '$Git_LoadCPAN_pm_path'!"; require File::Spec; - my $Git_pm_FromCPAN_root = File::Spec->catdir($Git_LoadCPAN_pm_root, 'FromCPAN'); + my $Git_pm_FromCPAN_root = File::Spec->catdir($Git_LoadCPAN_pm_root, '..', 'FromCPAN'); die "BUG: '$Git_pm_FromCPAN_root' should be a directory!" unless -d $Git_pm_FromCPAN_root; local @INC = ($Git_pm_FromCPAN_root, @INC); -- 2.15.1.424.g9478a66081
[PATCH v3 06/13] git-send-email: unconditionally use Net::{SMTP,Domain}
The Net::SMTP and Net::Domain were both first released with perl v5.7.3[1], since my d48b284183 ("perl: bump the required Perl version to 5.8 from 5.6.[21]", 2010-09-24) we've depended on 5.8, so there's no reason to conditionally require them anymore. This conditional loading was initially added in 87840620fd ("send-email: only 'require' instead of 'use' Net::SMTP", 2006-06-01) for Net::SMTP and 134550fe21 ("git-send-email.perl - try to give real name of the calling host to HELO/EHLO", 2010-03-14) for Net::Domain, both of which predate the hard dependency on 5.8. Since they're guaranteed to be installed now let's "use" them instead. The cost of loading them both is trivial given what git-send-email does (~15ms on my system), and it's better to not defer any potential loading errors until runtime. This patch is better viewed with -w, which shows that the only change in the last two hunks is removing the "if eval" wrapper block. 1. $ parallel 'corelist {}' ::: Net::{SMTP,Domain} Data for 2015-02-14 Net::SMTP was first released with perl v5.7.3 Data for 2015-02-14 Net::Domain was first released with perl v5.7.3 Signed-off-by: Ævar Arnfjörð Bjarmason--- git-send-email.perl | 24 +++- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/git-send-email.perl b/git-send-email.perl index bbf4deaa0d..d5a4826a1c 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -31,6 +31,8 @@ use Cwd qw(abs_path cwd); use Git; use Git::I18N; use Git::Mail::Address; +use Net::Domain (); +use Net::SMTP (); Getopt::Long::Configure qw/ pass_through /; @@ -1143,10 +1145,8 @@ sub valid_fqdn { sub maildomain_net { my $maildomain; - if (eval { require Net::Domain; 1 }) { - my $domain = Net::Domain::domainname(); - $maildomain = $domain if valid_fqdn($domain); - } + my $domain = Net::Domain::domainname(); + $maildomain = $domain if valid_fqdn($domain); return $maildomain; } @@ -1154,17 +1154,15 @@ sub maildomain_net { sub maildomain_mta { my $maildomain; - if (eval { require Net::SMTP; 1 }) { - for my $host (qw(mailhost localhost)) { - my $smtp = Net::SMTP->new($host); - if (defined $smtp) { - my $domain = $smtp->domain; - $smtp->quit; + for my $host (qw(mailhost localhost)) { + my $smtp = Net::SMTP->new($host); + if (defined $smtp) { + my $domain = $smtp->domain; + $smtp->quit; - $maildomain = $domain if valid_fqdn($domain); + $maildomain = $domain if valid_fqdn($domain); - last if $maildomain; - } + last if $maildomain; } } -- 2.15.1.424.g9478a66081
[PATCH v3 05/13] Git.pm: hard-depend on the File::{Temp,Spec} modules
Since my d48b284183 ("perl: bump the required Perl version to 5.8 from 5.6.[21]", 2010-09-24), we've depended on 5.8, so there's no reason to conditionally require File::Temp and File::Spec anymore. They were first released with perl versions v5.6.1 and 5.00405, respectively. This code was originally added in c14c8ceb13 ("Git.pm: Make File::Spec and File::Temp requirement lazy", 2008-08-15), presumably to make Git.pm work on 5.6.0. Signed-off-by: Ævar Arnfjörð Bjarmason--- perl/Git.pm | 10 ++ 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/perl/Git.pm b/perl/Git.pm index 7ec16e6dde..151b0e7144 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -11,6 +11,8 @@ use 5.008; use strict; use warnings; +use File::Temp (); +use File::Spec (); BEGIN { @@ -190,7 +192,6 @@ sub repository { }; if ($dir) { - _verify_require(); File::Spec->file_name_is_absolute($dir) or $dir = $opts{Directory} . '/' . $dir; $opts{Repository} = abs_path($dir); @@ -1289,8 +1290,6 @@ sub temp_release { sub _temp_cache { my ($self, $name) = _maybe_self(@_); - _verify_require(); - my $temp_fd = \$TEMP_FILEMAP{$name}; if (defined $$temp_fd and $$temp_fd->opened) { if ($TEMP_FILES{$$temp_fd}{locked}) { @@ -1324,11 +1323,6 @@ sub _temp_cache { $$temp_fd; } -sub _verify_require { - eval { require File::Temp; require File::Spec; }; - $@ and throw Error::Simple($@); -} - =item temp_reset ( FILEHANDLE ) Truncates and resets the position of the C. -- 2.15.1.424.g9478a66081
[PATCH v3 04/13] gitweb: hard-depend on the Digest::MD5 5.8 module
Since my d48b284183 ("perl: bump the required Perl version to 5.8 from 5.6.[21]", 2010-09-24), we've depended on 5.8, so there's no reason to conditionally require Digest::MD5 anymore. It was released with perl v5.7.3[1] The initial introduction of the dependency in e9fdd74e53 ("gitweb: (gr)avatar support", 2009-06-30) says as much, this also undoes part of the later 2e9c8789b7 ("gitweb: Mention optional Perl modules in INSTALL", 2011-02-04) since gitweb will always be run on at least 5.8, so there's no need to mention Digest::MD5 as a required module in the documentation, let's instead say that we require perl 5.8. 1. $ corelist Digest::MD5 Data for 2015-02-14 Digest::MD5 was first released with perl v5.7.3 Signed-off-by: Ævar Arnfjörð Bjarmason--- gitweb/INSTALL | 3 +-- gitweb/gitweb.perl | 17 - 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/gitweb/INSTALL b/gitweb/INSTALL index 408f2859d3..a58e6b3c44 100644 --- a/gitweb/INSTALL +++ b/gitweb/INSTALL @@ -29,12 +29,11 @@ Requirements - Core git tools - - Perl + - Perl 5.8 - Perl modules: CGI, Encode, Fcntl, File::Find, File::Basename. - web server The following optional Perl modules are required for extra features - - Digest::MD5 - for gravatar support - CGI::Fast and FCGI - for running gitweb as FastCGI script - HTML::TagCloud - for fancy tag cloud in project list view - HTTP::Date or Time::ParseDate - to support If-Modified-Since for feeds diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 2417057f2b..2594a4badb 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -20,6 +20,8 @@ use Fcntl ':mode'; use File::Find qw(); use File::Basename qw(basename); use Time::HiRes qw(gettimeofday tv_interval); +use Digest::MD5 qw(md5_hex); + binmode STDOUT, ':utf8'; if (!defined($CGI::VERSION) || $CGI::VERSION < 4.08) { @@ -490,7 +492,6 @@ our %feature = ( # Currently available providers are gravatar and picon. # If an unknown provider is specified, the feature is disabled. - # Gravatar depends on Digest::MD5. # Picon currently relies on the indiana.edu database. # To enable system wide have in $GITWEB_CONFIG @@ -1166,18 +1167,8 @@ sub configure_gitweb_features { our @snapshot_fmts = gitweb_get_feature('snapshot'); @snapshot_fmts = filter_snapshot_fmts(@snapshot_fmts); - # check that the avatar feature is set to a known provider name, - # and for each provider check if the dependencies are satisfied. - # if the provider name is invalid or the dependencies are not met, - # reset $git_avatar to the empty string. our ($git_avatar) = gitweb_get_feature('avatar'); - if ($git_avatar eq 'gravatar') { - $git_avatar = '' unless (eval { require Digest::MD5; 1; }); - } elsif ($git_avatar eq 'picon') { - # no dependencies - } else { - $git_avatar = ''; - } + $git_avatar = '' unless $git_avatar =~ /^(?:gravatar|picon)$/s; our @extra_branch_refs = gitweb_get_feature('extra-branch-refs'); @extra_branch_refs = filter_and_validate_refs (@extra_branch_refs); @@ -2167,7 +2158,7 @@ sub gravatar_url { my $size = shift; $avatar_cache{$email} ||= "//www.gravatar.com/avatar/" . - Digest::MD5::md5_hex($email) . "?s="; + md5_hex($email) . "?s="; return $avatar_cache{$email} . $size; } -- 2.15.1.424.g9478a66081
[PATCH v3 02/13] Git.pm: remove redundant "use strict" from sub-package
In Perl the "use strict/warnings" pragmas are lexical, thus there's no reason to do: package Foo; use strict; package Bar; use strict; $x = 5; To satisfy the desire that the undeclared $x variable will be spotted at compile-time. It's enough to include the first "use strict". This functionally changes nothing, but makes a subsequent change where "use warnings" will be added to Git.pm less confusing and less verbose, since as with "strict" we'll only need to do that at the top of the file. Changes code initially added in a6065b548f ("Git.pm: Try to support ActiveState output pipe", 2006-06-25). Signed-off-by: Ævar Arnfjörð Bjarmason--- perl/Git.pm | 1 - 1 file changed, 1 deletion(-) diff --git a/perl/Git.pm b/perl/Git.pm index 9d60d7948b..99e5d943af 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -1692,7 +1692,6 @@ sub DESTROY { # Pipe implementation for ActiveState Perl. package Git::activestate_pipe; -use strict; sub TIEHANDLE { my ($class, @params) = @_; -- 2.15.1.424.g9478a66081
[PATCH v3 03/13] Git.pm: add the "use warnings" pragma
Amend Git.pm to load the "warnings" pragma like the rest of the code in perl/ in addition to the existing "strict" pragma. This is considered the bare minimum best practice in Perl. Ever since this code was introduced in b1edc53d06 ("Introduce Git.pm (v4)", 2006-06-24) it's only been using "strict", not "warnings". This leaves contrib/buildsystems/Generators/{QMake,VCproj}.pm and contrib/mw-to-git/Git/Mediawiki.pm without "use warnings". Amending those would be a sensible follow-up change, but I don't have an easy way to test those so I'm not changing them. Signed-off-by: Ævar Arnfjörð Bjarmason--- perl/Git.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/perl/Git.pm b/perl/Git.pm index 99e5d943af..7ec16e6dde 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -9,6 +9,7 @@ package Git; use 5.008; use strict; +use warnings; BEGIN { -- 2.15.1.424.g9478a66081
[PATCH v3 01/13] perl: *.pm files should not have the executable bit
The Git::Mail::Address file added in bd869f67b9 ("send-email: add and use a local copy of Mail::Address", 2018-01-05) had the executable bit set. That bit should not be set for *.pm files. It breaks nothing but it is redundant and confusing as none of the other files have it and these files are never executed as stand-alone programs. Signed-off-by: Ævar Arnfjörð Bjarmason--- perl/Git/Mail/Address.pm | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 perl/Git/Mail/Address.pm diff --git a/perl/Git/Mail/Address.pm b/perl/Git/Mail/Address.pm old mode 100755 new mode 100644 -- 2.15.1.424.g9478a66081
[PATCH v3 00/13] various perl fixes
Same as v2 except rebased on master & a couple of commit message fixes, thanks to Eric Sunshine (thanks!). tbdiff with v2: 4: 0d67af28fb ! 4: 8ad874c944 gitweb: hard-depend on the Digest::MD5 5.8 module @@ -14,9 +14,6 @@ always be run on at least 5.8, so there's no need to mention Digest::MD5 as a required module in the documentation, let's instead say that we require perl 5.8. - -As with the preceding Net::{SMTP,Domain} change we now unconditionally -"use" the module instead. 1. $ corelist Digest::MD5 Data for 2015-02-14 [...] 6: 92429af3a3 ! 6: 3f44312821 git-send-email: unconditionally use Net::{SMTP,Domain} @@ -5,7 +5,7 @@ The Net::SMTP and Net::Domain were both first released with perl v5.7.3[1], since my d48b284183 ("perl: bump the required Perl version to 5.8 from 5.6.[21]", 2010-09-24) we've depended on 5.8, so there's -no reason to conditionally require this anymore. +no reason to conditionally require them anymore. This conditional loading was initially added in 87840620fd ("send-email: only 'require' instead of 'use' Net::SMTP", Todd Zullinger (1): Makefile: add NO_PERL_CPAN_FALLBACKS knob Ævar Arnfjörð Bjarmason (12): perl: *.pm files should not have the executable bit Git.pm: remove redundant "use strict" from sub-package Git.pm: add the "use warnings" pragma gitweb: hard-depend on the Digest::MD5 5.8 module Git.pm: hard-depend on the File::{Temp,Spec} modules git-send-email: unconditionally use Net::{SMTP,Domain} perl: update our ancient copy of Error.pm perl: update our copy of Mail::Address perl: move CPAN loader wrappers to another namespace perl: generalize the Git::LoadCPAN facility perl: move the perl/Git/FromCPAN tree to perl/FromCPAN perl Git::LoadCPAN: emit better errors under NO_PERL_CPAN_FALLBACKS INSTALL | 11 +- Makefile| 16 +- contrib/examples/git-difftool.perl | 2 +- git-send-email.perl | 28 ++- gitweb/INSTALL | 3 +- gitweb/gitweb.perl | 17 +- perl/FromCPAN/.gitattributes| 1 + perl/{Git => }/FromCPAN/Error.pm| 296 +++- perl/{Git => }/FromCPAN/Mail/Address.pm | 8 +- perl/Git.pm | 14 +- perl/Git/Error.pm | 46 - perl/Git/LoadCPAN.pm| 104 +++ perl/Git/LoadCPAN/Error.pm | 10 ++ perl/Git/LoadCPAN/Mail/Address.pm | 10 ++ perl/Git/Mail/Address.pm| 24 --- 15 files changed, 432 insertions(+), 158 deletions(-) create mode 100644 perl/FromCPAN/.gitattributes rename perl/{Git => }/FromCPAN/Error.pm (72%) rename perl/{Git => }/FromCPAN/Mail/Address.pm (96%) delete mode 100644 perl/Git/Error.pm create mode 100644 perl/Git/LoadCPAN.pm create mode 100644 perl/Git/LoadCPAN/Error.pm create mode 100644 perl/Git/LoadCPAN/Mail/Address.pm delete mode 100755 perl/Git/Mail/Address.pm -- 2.15.1.424.g9478a66081
Re: t006 broken under Mac OS
On Sat, Mar 03, 2018 at 01:52:05PM +0100, Torsten Bögershausen wrote: > Beside that t1006 has a broken indentation (mixed spaces and TABs at > the beginning of the line, I get 4 errors here under Mac OS: > > not ok 15 - Check %(refname) gives empty output > not ok 36 - Check %(refname) gives empty output > not ok 58 - Check %(refname) gives empty output > not ok 89 - Check %(refname) gives empty output > > > Running with debug and verbose shows that the empty files are not empty. > The characters in the non-empty file are outside the ASCII range, > so I copy the stuff in here after running `od -c` on the log file. > And I don't have a clue, where this stuff comes from - but I get different > "crap" with each run - seams as if there is a read behind a buffer ? Yeah, I think the ref_array_item.refname flex-parameter is not valid. This is the same issue Ramsay mentioned in: https://public-inbox.org/git/58b2bdcd-d621-fd21-ab4d-6a9478319...@ramsayjones.plus.com/ Junio, I think it probably makes sense to eject ot/cat-batch-format from pu for now. That series is on pause for a bit while Olga works on some other refactoring, and it's causing problems for people who test pu regularly. -Peff
RE: [PATCH 0/3] git worktree prune improvements
On March 2, 2018 10:39 PM, Nguy?n Thái Ng?c Duy wrote: > This is something we could do to improve the situation when a user manually > moves a worktree and not follow the update process (we have had the first > reported case [1]). Plus a bit cleanup in gc. > > I think this is something we should do until we somehow make the user > aware that the worktree is broken as soon as they move a worktree > manually. But there's some more work to get there. > > [1] http://public-inbox.org/git/%3Caa98f187-4b1a-176d-2a1b- > 826c99577...@aegee.org%3E I wonder whether the OT thread discussion about branch annotation may have some value here. For some repositories I manage, I have received questions about whether there was some way to know that a branch in the clone was associated with a worktree "at any point in the past", which, once the worktree has been pruned, is not derivable in a formal computational sense - there may be specific conditions where it is. Perhaps, if that line of development moves forward, that we should considering annotating the worktree-created branch to help with our pruning process and to identify where the branch originated. Just a thought. Cheers, Randall -- Brief whoami: NonStop developer since approximately NonStop(2112884442) UNIX developer since approximately 421664400 -- In my real life, I talk too much.
Re: [PATCH 2/2] completion: simplify _git_notes
On Sat, Mar 3, 2018 at 10:23 AM, Nguyễn Thái Ngọc Duywrote: > This also adds completion for 'git notes remove' with two options: > --ignore-missing and --stdin. > > For some strange reason, 'git notes undefined --' completes --ref > without even running --git-completion-helper. But since this is an error > case (and we're not doing anything destructive, it's probably ok for now) > > Signed-off-by: Nguyễn Thái Ngọc Duy > --- > contrib/completion/git-completion.bash | 15 ++- > 1 file changed, 2 insertions(+), 13 deletions(-) > > diff --git a/contrib/completion/git-completion.bash > b/contrib/completion/git-completion.bash > index c310b241d3..ab80f4e6e8 100644 > --- a/contrib/completion/git-completion.bash > +++ b/contrib/completion/git-completion.bash > @@ -1836,19 +1836,8 @@ _git_notes () > add,--reedit-message=*|append,--reedit-message=*) > __git_complete_refs --cur="${cur#*=}" > ;; > - add,--*) > - __gitcomp_builtin notes_add > - ;; > - append,--*) > - __gitcomp_builtin notes_append > - ;; > - copy,--*) > - __gitcomp_builtin notes_copy > - ;; > - prune,--*) > - __gitcomp_builtin notes_prune > - ;; > - prune,*) There is a minor behaviour change here, though. This prune,*) ;; case arm ensured that we don't list refs for 'git notes prune ', because it doesn't accept them (and then we take our usual fallback and let Bash complete filenames; yeah, 'git notes prune' doesn't accept filenames either, but, as I said, that's our usual fallback when we can't offer anything for completion). This patch removes that case arm, and refs will be offered for 'git notes prune '. > + *,--*) > + __gitcomp_builtin notes_$subcommand > ;; > *) > case "$prev" in > -- > 2.16.1.435.g8f24da2e1a >
t006 broken under Mac OS
Hej, Beside that t1006 has a broken indentation (mixed spaces and TABs at the beginning of the line, I get 4 errors here under Mac OS: not ok 15 - Check %(refname) gives empty output not ok 36 - Check %(refname) gives empty output not ok 58 - Check %(refname) gives empty output not ok 89 - Check %(refname) gives empty output Running with debug and verbose shows that the empty files are not empty. The characters in the non-empty file are outside the ASCII range, so I copy the stuff in here after running `od -c` on the log file. And I don't have a clue, where this stuff comes from - but I get different "crap" with each run - seams as if there is a read behind a buffer ? 15: 00060000 \n @ @ - 1 + 1 @ @ \n - \n 0006020+ 361 r 0 360 024 254 \n n o t o k 1 00060405 - C h e c k % ( r e f n 0006060a m e ) g i v e s e m p t y 0006100o u t p u t \n # \t \n # \t \t e c 36: 0016220- 1 + 1 @ @ \n - \n + 225 x < e 0016240 240 @ \n n o t o k 3 6 - C 0016260h e c k % ( r e f n a m e ) 0016300g i v e s e m p t y o u t p 0016320u t \n # \t \n # \t \t e c h o " $ 58: 0027120 \n @ @ - 1 + 1 @ @ \n - \n + 0027140 302 206 \a 4 220 311 \n n o t o k 5 8 0027160- C h e c k % ( r e f n a 0027200m e ) g i v e s e m p t y 0027220o u t p u t \n # \t \n # \t \t e c h 89: 00431600 0 0 \n @ @ - 1 + 1 @ @ \n 0043200- \n + p 034 276 034 ! ; \n n o t o k 00432208 9 - C h e c k % ( r e 0043240f n a m e ) g i v e s e m p 0043260t y o u t p u t \n # \t \n # \t \t
Re: [PATCH 2/2] completion: simplify _git_notes
On Sat, Mar 3, 2018 at 10:23 AM, Nguyễn Thái Ngọc Duywrote: > This also adds completion for 'git notes remove' with two options: > --ignore-missing and --stdin. > > For some strange reason, 'git notes undefined --' completes --ref > without even running --git-completion-helper. There is nothing strange about it. _git_notes() first looks for the presence of any subcommands on the command line, and if it doesn't find any, it will list 'git notes's subcommands and options for completion. And it does so by running '__gitcomp "$subcommands --ref"' > But since this is an error > case (and we're not doing anything destructive, it's probably ok for now) I agree; and it matches the behaviour before the patch. > Signed-off-by: Nguyễn Thái Ngọc Duy > --- > contrib/completion/git-completion.bash | 15 ++- > 1 file changed, 2 insertions(+), 13 deletions(-) > > diff --git a/contrib/completion/git-completion.bash > b/contrib/completion/git-completion.bash > index c310b241d3..ab80f4e6e8 100644 > --- a/contrib/completion/git-completion.bash > +++ b/contrib/completion/git-completion.bash > @@ -1836,19 +1836,8 @@ _git_notes () > add,--reedit-message=*|append,--reedit-message=*) > __git_complete_refs --cur="${cur#*=}" > ;; > - add,--*) > - __gitcomp_builtin notes_add > - ;; > - append,--*) > - __gitcomp_builtin notes_append > - ;; > - copy,--*) > - __gitcomp_builtin notes_copy > - ;; > - prune,--*) > - __gitcomp_builtin notes_prune > - ;; > - prune,*) > + *,--*) > + __gitcomp_builtin notes_$subcommand > ;; > *) > case "$prev" in > -- > 2.16.1.435.g8f24da2e1a >
[PATCH 41/44] packfile: allow reprepare_packed_git to handle arbitrary repositories
From: Stefan BellerSigned-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- packfile.c | 8 packfile.h | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packfile.c b/packfile.c index 2276e2ad26..fbf5d56754 100644 --- a/packfile.c +++ b/packfile.c @@ -897,11 +897,11 @@ void prepare_packed_git(struct repository *r) r->objects.packed_git_initialized = 1; } -void reprepare_packed_git_the_repository(void) +void reprepare_packed_git(struct repository *r) { - the_repository->objects.approximate_object_count_valid = 0; - the_repository->objects.packed_git_initialized = 0; - prepare_packed_git(the_repository); + r->objects.approximate_object_count_valid = 0; + r->objects.packed_git_initialized = 0; + prepare_packed_git(r); } struct packed_git *get_packed_git(struct repository *r) diff --git a/packfile.h b/packfile.h index 3fd9092472..ee6da3a9ae 100644 --- a/packfile.h +++ b/packfile.h @@ -35,8 +35,7 @@ extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_ extern void (*report_garbage)(unsigned seen_bits, const char *path); extern void prepare_packed_git(struct repository *r); -#define reprepare_packed_git(r) reprepare_packed_git_##r() -extern void reprepare_packed_git_the_repository(void); +extern void reprepare_packed_git(struct repository *r); extern void install_packed_git(struct repository *r, struct packed_git *pack); struct packed_git *get_packed_git(struct repository *r); -- 2.16.1.435.g8f24da2e1a
[PATCH 33/44] packfile: allow prepare_packed_git_mru to handle arbitrary repositories
From: Stefan BellerThis conversion was done without the #define trick used in the earlier series refactoring to have better repository access, because this function is easy to review, as all lines are converted and it has only one caller Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- packfile.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packfile.c b/packfile.c index a0842521e5..0eaf5ee100 100644 --- a/packfile.c +++ b/packfile.c @@ -872,14 +872,14 @@ static void rearrange_packed_git(void) set_next_packed_git, sort_pack); } -static void prepare_packed_git_mru(void) +static void prepare_packed_git_mru(struct repository *r) { struct packed_git *p; - INIT_LIST_HEAD(_repository->objects.packed_git_mru); + INIT_LIST_HEAD(>objects.packed_git_mru); - for (p = the_repository->objects.packed_git; p; p = p->next) - list_add_tail(>mru, _repository->objects.packed_git_mru); + for (p = r->objects.packed_git; p; p = p->next) + list_add_tail(>mru, >objects.packed_git_mru); } void prepare_packed_git(void) @@ -893,7 +893,7 @@ void prepare_packed_git(void) for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) prepare_packed_git_one(alt->path, 0); rearrange_packed_git(); - prepare_packed_git_mru(); + prepare_packed_git_mru(the_repository); the_repository->objects.packed_git_initialized = 1; } -- 2.16.1.435.g8f24da2e1a
[PATCH 42/44] packfile: add repository argument to find_pack_entry
From: Stefan BellerWhile at it move the documentation to the header and mention which pack files are searched. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- packfile.c | 8 ++-- packfile.h | 7 ++- sha1_file.c | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/packfile.c b/packfile.c index fbf5d56754..7388debbb2 100644 --- a/packfile.c +++ b/packfile.c @@ -1844,11 +1844,7 @@ static int fill_pack_entry(const unsigned char *sha1, return 1; } -/* - * Iff a pack file contains the object named by sha1, return true and - * store its location to e. - */ -int find_pack_entry(const unsigned char *sha1, struct pack_entry *e) +int find_pack_entry_the_repository(const unsigned char *sha1, struct pack_entry *e) { struct list_head *pos; @@ -1870,7 +1866,7 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e) int has_sha1_pack(const unsigned char *sha1) { struct pack_entry e; - return find_pack_entry(sha1, ); + return find_pack_entry(the_repository, sha1, ); } int has_pack_index(const unsigned char *sha1) diff --git a/packfile.h b/packfile.h index ee6da3a9ae..e68f790ea7 100644 --- a/packfile.h +++ b/packfile.h @@ -123,7 +123,12 @@ extern int packed_object_info(struct packed_git *pack, off_t offset, struct obje extern void mark_bad_packed_object(struct packed_git *p, const unsigned char *sha1); extern const struct packed_git *has_packed_and_bad(const unsigned char *sha1); -extern int find_pack_entry(const unsigned char *sha1, struct pack_entry *e); +/* + * Iff a pack file in the given repository contains the object named by sha1, + * return true and store its location to e. + */ +#define find_pack_entry(r, s, e) find_pack_entry_##r(s, e) +extern int find_pack_entry_the_repository(const unsigned char *sha1, struct pack_entry *e); extern int has_sha1_pack(const unsigned char *sha1); diff --git a/sha1_file.c b/sha1_file.c index be84f84373..ba47963e63 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1266,7 +1266,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi, } while (1) { - if (find_pack_entry(real, )) + if (find_pack_entry(the_repository, real, )) break; /* Most likely it's a loose object. */ @@ -1275,7 +1275,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi, /* Not a loose object; someone else may have just packed it. */ reprepare_packed_git(the_repository); - if (find_pack_entry(real, )) + if (find_pack_entry(the_repository, real, )) break; /* Check if it is a missing object */ @@ -1655,7 +1655,7 @@ static int freshen_loose_object(const unsigned char *sha1) static int freshen_packed_object(const unsigned char *sha1) { struct pack_entry e; - if (!find_pack_entry(sha1, )) + if (!find_pack_entry(the_repository, sha1, )) return 0; if (e.p->freshened) return 1; -- 2.16.1.435.g8f24da2e1a
[PATCH 44/44] packfile: keep prepare_packed_git() private
The reason callers have to call this is to make sure either packed_git or packed_git_mru pointers are initialized since we don't do that by default. Sometimes it's hard to see this connection between where the function is called and where packed_git pointer is used (sometimes in separate functions). Keep this dependency internal because now all access to packed_git and packed_git_mru must go through get_xxx() wrappers. Signed-off-by: Nguyễn Thái Ngọc Duy--- builtin/count-objects.c | 3 +-- builtin/fsck.c | 2 -- builtin/gc.c | 1 - builtin/pack-objects.c | 1 - builtin/pack-redundant.c | 2 -- fast-import.c| 1 - http-backend.c | 1 - pack-bitmap.c| 1 - packfile.c | 5 - packfile.h | 1 - server-info.c| 1 - sha1_name.c | 2 -- 12 files changed, 5 insertions(+), 16 deletions(-) diff --git a/builtin/count-objects.c b/builtin/count-objects.c index 2793c98ed3..ee6ae35244 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -121,8 +121,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix) struct strbuf loose_buf = STRBUF_INIT; struct strbuf pack_buf = STRBUF_INIT; struct strbuf garbage_buf = STRBUF_INIT; - if (!get_packed_git(the_repository)) - prepare_packed_git(the_repository); + for (p = get_packed_git(the_repository); p; p = p->next) { if (!p->pack_local) continue; diff --git a/builtin/fsck.c b/builtin/fsck.c index 7a3e323e9e..9911c52bc8 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -726,8 +726,6 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) uint32_t total = 0, count = 0; struct progress *progress = NULL; - prepare_packed_git(the_repository); - if (show_progress) { for (p = get_packed_git(the_repository); p; p = p->next) { diff --git a/builtin/gc.c b/builtin/gc.c index 560d58daec..be63bec09c 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -173,7 +173,6 @@ static int too_many_packs(void) if (gc_auto_pack_limit <= 0) return 0; - prepare_packed_git(the_repository); for (cnt = 0, p = get_packed_git(the_repository); p; p = p->next) { if (!p->pack_local) continue; diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 6020a7e230..435f091a69 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -3151,7 +3151,6 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) if (progress && all_progress_implied) progress = 2; - prepare_packed_git(the_repository); if (ignore_packed_keep) { struct packed_git *p; for (p = get_packed_git(the_repository); p; p = p->next) diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index bf42e164eb..02b5f0becc 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -630,8 +630,6 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix) break; } - prepare_packed_git(the_repository); - if (load_all_packs) load_all(); else diff --git a/fast-import.c b/fast-import.c index 985eb2eccc..2298bfcdfd 100644 --- a/fast-import.c +++ b/fast-import.c @@ -3472,7 +3472,6 @@ int cmd_main(int argc, const char **argv) rc_free[i].next = _free[i + 1]; rc_free[cmd_save - 1].next = NULL; - prepare_packed_git(the_repository); start_packfile(); set_die_routine(die_nicely); set_checkpoint_signal(); diff --git a/http-backend.c b/http-backend.c index 659ddfb5f1..22d2e1668e 100644 --- a/http-backend.c +++ b/http-backend.c @@ -518,7 +518,6 @@ static void get_info_packs(struct strbuf *hdr, char *arg) size_t cnt = 0; select_getanyfile(hdr); - prepare_packed_git(the_repository); for (p = get_packed_git(the_repository); p; p = p->next) { if (p->pack_local) cnt++; diff --git a/pack-bitmap.c b/pack-bitmap.c index 01c9cd1642..2a007b5539 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -335,7 +335,6 @@ static int open_pack_bitmap(void) assert(!bitmap_git.map && !bitmap_git.loaded); - prepare_packed_git(the_repository); for (p = get_packed_git(the_repository); p; p = p->next) { if (open_pack_bitmap_1(p) == 0) ret = 0; diff --git a/packfile.c b/packfile.c index bafe81544d..773cd99a13 100644 --- a/packfile.c +++ b/packfile.c @@ -802,6 +802,7 @@ static void prepare_packed_git_one(struct repository *r, char
[PATCH 39/44] packfile: allow prepare_packed_git_one to handle arbitrary repositories
From: Stefan BellerSigned-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- packfile.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packfile.c b/packfile.c index 53db240d0f..52febba932 100644 --- a/packfile.c +++ b/packfile.c @@ -734,8 +734,7 @@ static void report_pack_garbage(struct string_list *list) report_helper(list, seen_bits, first, list->nr); } -#define prepare_packed_git_one(r, o, l) prepare_packed_git_one_##r(o, l) -static void prepare_packed_git_one_the_repository(char *objdir, int local) +static void prepare_packed_git_one(struct repository *r, char *objdir, int local) { struct strbuf path = STRBUF_INIT; size_t dirnamelen; @@ -768,7 +767,7 @@ static void prepare_packed_git_one_the_repository(char *objdir, int local) base_len = path.len; if (strip_suffix_mem(path.buf, _len, ".idx")) { /* Don't reopen a pack we already have. */ - for (p = the_repository->objects.packed_git; p; + for (p = r->objects.packed_git; p; p = p->next) { size_t len; if (strip_suffix(p->pack_name, ".pack", ) && @@ -782,7 +781,7 @@ static void prepare_packed_git_one_the_repository(char *objdir, int local) * corresponding .pack file that we can map. */ (p = add_packed_git(path.buf, path.len, local)) != NULL) - install_packed_git(the_repository, p); + install_packed_git(r, p); } if (!report_garbage) -- 2.16.1.435.g8f24da2e1a
[PATCH 40/44] packfile: allow prepare_packed_git to handle arbitrary repositories
From: Stefan BellerSigned-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- packfile.c | 18 +- packfile.h | 3 +-- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/packfile.c b/packfile.c index 52febba932..2276e2ad26 100644 --- a/packfile.c +++ b/packfile.c @@ -882,19 +882,19 @@ static void prepare_packed_git_mru(struct repository *r) list_add_tail(>mru, >objects.packed_git_mru); } -void prepare_packed_git_the_repository(void) +void prepare_packed_git(struct repository *r) { struct alternate_object_database *alt; - if (the_repository->objects.packed_git_initialized) + if (r->objects.packed_git_initialized) return; - prepare_packed_git_one(the_repository, get_object_directory(), 1); - prepare_alt_odb(the_repository); - for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) - prepare_packed_git_one(the_repository, alt->path, 0); - rearrange_packed_git(the_repository); - prepare_packed_git_mru(the_repository); - the_repository->objects.packed_git_initialized = 1; + prepare_packed_git_one(r, get_object_directory(), 1); + prepare_alt_odb(r); + for (alt = r->objects.alt_odb_list; alt; alt = alt->next) + prepare_packed_git_one(r, alt->path, 0); + rearrange_packed_git(r); + prepare_packed_git_mru(r); + r->objects.packed_git_initialized = 1; } void reprepare_packed_git_the_repository(void) diff --git a/packfile.h b/packfile.h index ab5046938c..3fd9092472 100644 --- a/packfile.h +++ b/packfile.h @@ -34,8 +34,7 @@ extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_ #define PACKDIR_FILE_GARBAGE 4 extern void (*report_garbage)(unsigned seen_bits, const char *path); -#define prepare_packed_git(r) prepare_packed_git_##r() -extern void prepare_packed_git_the_repository(void); +extern void prepare_packed_git(struct repository *r); #define reprepare_packed_git(r) reprepare_packed_git_##r() extern void reprepare_packed_git_the_repository(void); extern void install_packed_git(struct repository *r, struct packed_git *pack); -- 2.16.1.435.g8f24da2e1a
[PATCH 37/44] packfile: add repository argument to prepare_packed_git
From: Stefan BellerAdd a repository argument to allow prepare_packed_git callers to be more specific about which repository to handle. See c28d027a52c (sha1_file: add repository argument to link_alt_odb_entry, 2018-02-20) for an explanation of the #define trick. Signed-off-by: Stefan Beller Signed-off-by: Nguyễn Thái Ngọc Duy --- builtin/count-objects.c | 2 +- builtin/fsck.c | 2 +- builtin/gc.c | 2 +- builtin/pack-objects.c | 2 +- builtin/pack-redundant.c | 2 +- fast-import.c| 2 +- http-backend.c | 2 +- pack-bitmap.c| 2 +- packfile.c | 10 +- packfile.h | 3 ++- server-info.c| 2 +- sha1_name.c | 4 ++-- 12 files changed, 18 insertions(+), 17 deletions(-) diff --git a/builtin/count-objects.c b/builtin/count-objects.c index 5c7c3c6ae3..2793c98ed3 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -122,7 +122,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix) struct strbuf pack_buf = STRBUF_INIT; struct strbuf garbage_buf = STRBUF_INIT; if (!get_packed_git(the_repository)) - prepare_packed_git(); + prepare_packed_git(the_repository); for (p = get_packed_git(the_repository); p; p = p->next) { if (!p->pack_local) continue; diff --git a/builtin/fsck.c b/builtin/fsck.c index b0abba6e04..7a3e323e9e 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -726,7 +726,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) uint32_t total = 0, count = 0; struct progress *progress = NULL; - prepare_packed_git(); + prepare_packed_git(the_repository); if (show_progress) { for (p = get_packed_git(the_repository); p; diff --git a/builtin/gc.c b/builtin/gc.c index dd30067ac1..526f06173e 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -173,7 +173,7 @@ static int too_many_packs(void) if (gc_auto_pack_limit <= 0) return 0; - prepare_packed_git(); + prepare_packed_git(the_repository); for (cnt = 0, p = get_packed_git(the_repository); p; p = p->next) { if (!p->pack_local) continue; diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 0e5fde1d6b..6020a7e230 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -3151,7 +3151,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) if (progress && all_progress_implied) progress = 2; - prepare_packed_git(); + prepare_packed_git(the_repository); if (ignore_packed_keep) { struct packed_git *p; for (p = get_packed_git(the_repository); p; p = p->next) diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index d6d8a44959..bf42e164eb 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -630,7 +630,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix) break; } - prepare_packed_git(); + prepare_packed_git(the_repository); if (load_all_packs) load_all(); diff --git a/fast-import.c b/fast-import.c index ec78e8ff47..985eb2eccc 100644 --- a/fast-import.c +++ b/fast-import.c @@ -3472,7 +3472,7 @@ int cmd_main(int argc, const char **argv) rc_free[i].next = _free[i + 1]; rc_free[cmd_save - 1].next = NULL; - prepare_packed_git(); + prepare_packed_git(the_repository); start_packfile(); set_die_routine(die_nicely); set_checkpoint_signal(); diff --git a/http-backend.c b/http-backend.c index 22921d169a..659ddfb5f1 100644 --- a/http-backend.c +++ b/http-backend.c @@ -518,7 +518,7 @@ static void get_info_packs(struct strbuf *hdr, char *arg) size_t cnt = 0; select_getanyfile(hdr); - prepare_packed_git(); + prepare_packed_git(the_repository); for (p = get_packed_git(the_repository); p; p = p->next) { if (p->pack_local) cnt++; diff --git a/pack-bitmap.c b/pack-bitmap.c index abed43cdb5..01c9cd1642 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -335,7 +335,7 @@ static int open_pack_bitmap(void) assert(!bitmap_git.map && !bitmap_git.loaded); - prepare_packed_git(); + prepare_packed_git(the_repository); for (p = get_packed_git(the_repository); p; p = p->next) { if (open_pack_bitmap_1(p) == 0) ret = 0; diff --git a/packfile.c b/packfile.c index d7658e6c45..b5ad6838f8 100644 --- a/packfile.c +++
[PATCH 43/44] packfile: allow find_pack_entry to handle arbitrary repositories
From: Stefan BellerSigned-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- packfile.c | 11 +-- packfile.h | 3 +-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/packfile.c b/packfile.c index 7388debbb2..bafe81544d 100644 --- a/packfile.c +++ b/packfile.c @@ -1844,19 +1844,18 @@ static int fill_pack_entry(const unsigned char *sha1, return 1; } -int find_pack_entry_the_repository(const unsigned char *sha1, struct pack_entry *e) +int find_pack_entry(struct repository *r, const unsigned char *sha1, struct pack_entry *e) { struct list_head *pos; - prepare_packed_git(the_repository); - if (!the_repository->objects.packed_git) + prepare_packed_git(r); + if (!r->objects.packed_git) return 0; - list_for_each(pos, _repository->objects.packed_git_mru) { + list_for_each(pos, >objects.packed_git_mru) { struct packed_git *p = list_entry(pos, struct packed_git, mru); if (fill_pack_entry(sha1, e, p)) { - list_move(>mru, - _repository->objects.packed_git_mru); + list_move(>mru, >objects.packed_git_mru); return 1; } } diff --git a/packfile.h b/packfile.h index e68f790ea7..fe1a6380e6 100644 --- a/packfile.h +++ b/packfile.h @@ -127,8 +127,7 @@ extern const struct packed_git *has_packed_and_bad(const unsigned char *sha1); * Iff a pack file in the given repository contains the object named by sha1, * return true and store its location to e. */ -#define find_pack_entry(r, s, e) find_pack_entry_##r(s, e) -extern int find_pack_entry_the_repository(const unsigned char *sha1, struct pack_entry *e); +extern int find_pack_entry(struct repository *r, const unsigned char *sha1, struct pack_entry *e); extern int has_sha1_pack(const unsigned char *sha1); -- 2.16.1.435.g8f24da2e1a
[PATCH 38/44] packfile: add repository argument to reprepare_packed_git
From: Stefan BellerSee previous patch for explanation. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- builtin/gc.c | 2 +- builtin/receive-pack.c | 3 ++- bulk-checkin.c | 3 ++- fetch-pack.c | 3 ++- packfile.c | 2 +- packfile.h | 3 ++- sha1_file.c| 2 +- 7 files changed, 11 insertions(+), 7 deletions(-) diff --git a/builtin/gc.c b/builtin/gc.c index 526f06173e..560d58daec 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -477,7 +477,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix) return error(FAILED_RUN, rerere.argv[0]); report_garbage = report_pack_garbage; - reprepare_packed_git(); + reprepare_packed_git(the_repository); if (pack_garbage.nr > 0) clean_pack_garbage(); diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index ac478b7b99..dfc69be1a2 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -1,4 +1,5 @@ #include "builtin.h" +#include "repository.h" #include "config.h" #include "lockfile.h" #include "pack.h" @@ -1777,7 +1778,7 @@ static const char *unpack(int err_fd, struct shallow_info *si) status = finish_command(); if (status) return "index-pack abnormal exit"; - reprepare_packed_git(); + reprepare_packed_git(the_repository); } return NULL; } diff --git a/bulk-checkin.c b/bulk-checkin.c index 3310fd210a..eadc2d5172 100644 --- a/bulk-checkin.c +++ b/bulk-checkin.c @@ -3,6 +3,7 @@ */ #include "cache.h" #include "bulk-checkin.h" +#include "repository.h" #include "csum-file.h" #include "pack.h" #include "strbuf.h" @@ -57,7 +58,7 @@ static void finish_bulk_checkin(struct bulk_checkin_state *state) strbuf_release(); /* Make objects we just wrote available to ourselves */ - reprepare_packed_git(); + reprepare_packed_git(the_repository); } static int already_written(struct bulk_checkin_state *state, unsigned char sha1[]) diff --git a/fetch-pack.c b/fetch-pack.c index 8253d746e0..eac5928a27 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -1,4 +1,5 @@ #include "cache.h" +#include "repository.h" #include "config.h" #include "lockfile.h" #include "refs.h" @@ -1192,7 +1193,7 @@ struct ref *fetch_pack(struct fetch_pack_args *args, prepare_shallow_info(, shallow); ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought, , pack_lockfile); - reprepare_packed_git(); + reprepare_packed_git(the_repository); update_shallow(args, sought, nr_sought, ); clear_shallow_info(); return ref_cpy; diff --git a/packfile.c b/packfile.c index b5ad6838f8..53db240d0f 100644 --- a/packfile.c +++ b/packfile.c @@ -898,7 +898,7 @@ void prepare_packed_git_the_repository(void) the_repository->objects.packed_git_initialized = 1; } -void reprepare_packed_git(void) +void reprepare_packed_git_the_repository(void) { the_repository->objects.approximate_object_count_valid = 0; the_repository->objects.packed_git_initialized = 0; diff --git a/packfile.h b/packfile.h index 3f59456e7e..ab5046938c 100644 --- a/packfile.h +++ b/packfile.h @@ -36,7 +36,8 @@ extern void (*report_garbage)(unsigned seen_bits, const char *path); #define prepare_packed_git(r) prepare_packed_git_##r() extern void prepare_packed_git_the_repository(void); -extern void reprepare_packed_git(void); +#define reprepare_packed_git(r) reprepare_packed_git_##r() +extern void reprepare_packed_git_the_repository(void); extern void install_packed_git(struct repository *r, struct packed_git *pack); struct packed_git *get_packed_git(struct repository *r); diff --git a/sha1_file.c b/sha1_file.c index 7066d4c9ce..be84f84373 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1274,7 +1274,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi, return 0; /* Not a loose object; someone else may have just packed it. */ - reprepare_packed_git(); + reprepare_packed_git(the_repository); if (find_pack_entry(real, )) break; -- 2.16.1.435.g8f24da2e1a
[PATCH 35/44] packfile: allow install_packed_git to handle arbitrary repositories
From: Stefan BellerThis conversion was done without the #define trick used in the earlier series refactoring to have better repository access, because this function is easy to review, as it only has one caller and all lines but the first two are converted. We must not convert 'pack_open_fds' to be a repository specific variable, as it is used to monitor resource usage of the machine that Git executes on. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- fast-import.c | 2 +- http.c| 2 +- packfile.c| 8 packfile.h| 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/fast-import.c b/fast-import.c index 0dba555478..ec78e8ff47 100644 --- a/fast-import.c +++ b/fast-import.c @@ -1037,7 +1037,7 @@ static void end_packfile(void) if (!new_p) die("core git rejected index %s", idx_name); all_packs[pack_id] = new_p; - install_packed_git(new_p); + install_packed_git(the_repository, new_p); free(idx_name); /* Print the boundary */ diff --git a/http.c b/http.c index df9dbea59c..649656b87c 100644 --- a/http.c +++ b/http.c @@ -2133,7 +2133,7 @@ int finish_http_pack_request(struct http_pack_request *preq) return -1; } - install_packed_git(p); + install_packed_git(the_repository, p); free(tmp_idx); return 0; } diff --git a/packfile.c b/packfile.c index 5356712717..ba185daec2 100644 --- a/packfile.c +++ b/packfile.c @@ -679,13 +679,13 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local) return p; } -void install_packed_git(struct packed_git *pack) +void install_packed_git(struct repository *r, struct packed_git *pack) { if (pack->pack_fd != -1) pack_open_fds++; - pack->next = the_repository->objects.packed_git; - the_repository->objects.packed_git = pack; + pack->next = r->objects.packed_git; + r->objects.packed_git = pack; } void (*report_garbage)(unsigned seen_bits, const char *path); @@ -781,7 +781,7 @@ static void prepare_packed_git_one(char *objdir, int local) * corresponding .pack file that we can map. */ (p = add_packed_git(path.buf, path.len, local)) != NULL) - install_packed_git(p); + install_packed_git(the_repository, p); } if (!report_garbage) diff --git a/packfile.h b/packfile.h index 5b1ce00f84..77442172f0 100644 --- a/packfile.h +++ b/packfile.h @@ -36,7 +36,7 @@ extern void (*report_garbage)(unsigned seen_bits, const char *path); extern void prepare_packed_git(void); extern void reprepare_packed_git(void); -extern void install_packed_git(struct packed_git *pack); +extern void install_packed_git(struct repository *r, struct packed_git *pack); struct packed_git *get_packed_git(struct repository *r); struct list_head *get_packed_git_mru(struct repository *r); -- 2.16.1.435.g8f24da2e1a
[PATCH 34/44] packfile: allow rearrange_packed_git to handle arbitrary repositories
From: Stefan BellerSigned-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- packfile.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packfile.c b/packfile.c index 0eaf5ee100..5356712717 100644 --- a/packfile.c +++ b/packfile.c @@ -865,10 +865,10 @@ static int sort_pack(const void *a_, const void *b_) return -1; } -static void rearrange_packed_git(void) +static void rearrange_packed_git(struct repository *r) { - the_repository->objects.packed_git = llist_mergesort( - the_repository->objects.packed_git, get_next_packed_git, + r->objects.packed_git = llist_mergesort( + r->objects.packed_git, get_next_packed_git, set_next_packed_git, sort_pack); } @@ -892,7 +892,7 @@ void prepare_packed_git(void) prepare_alt_odb(the_repository); for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) prepare_packed_git_one(alt->path, 0); - rearrange_packed_git(); + rearrange_packed_git(the_repository); prepare_packed_git_mru(the_repository); the_repository->objects.packed_git_initialized = 1; } -- 2.16.1.435.g8f24da2e1a
[PATCH 31/44] sha1_file: allow map_sha1_file to handle arbitrary repositories
From: Stefan BellerSigned-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- object-store.h | 3 +-- sha1_file.c| 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/object-store.h b/object-store.h index 98622a2b98..521f5a1755 100644 --- a/object-store.h +++ b/object-store.h @@ -121,7 +121,6 @@ void raw_object_store_clear(struct raw_object_store *o); */ void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1); -#define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz) -void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size); +void *map_sha1_file(struct repository *r, const unsigned char *sha1, unsigned long *size); #endif /* OBJECT_STORE_H */ diff --git a/sha1_file.c b/sha1_file.c index d4678f8162..c5a8b00aed 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -957,9 +957,10 @@ static void *map_sha1_file_1(struct repository *r, const char *path, return map; } -void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size) +void *map_sha1_file(struct repository *r, + const unsigned char *sha1, unsigned long *size) { - return map_sha1_file_1(the_repository, NULL, sha1, size); + return map_sha1_file_1(r, NULL, sha1, size); } static int unpack_sha1_short_header(git_zstream *stream, -- 2.16.1.435.g8f24da2e1a
[PATCH 36/44] packfile: add repository argument to prepare_packed_git_one
From: Stefan BellerSigned-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- packfile.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packfile.c b/packfile.c index ba185daec2..d7658e6c45 100644 --- a/packfile.c +++ b/packfile.c @@ -734,7 +734,8 @@ static void report_pack_garbage(struct string_list *list) report_helper(list, seen_bits, first, list->nr); } -static void prepare_packed_git_one(char *objdir, int local) +#define prepare_packed_git_one(r, o, l) prepare_packed_git_one_##r(o, l) +static void prepare_packed_git_one_the_repository(char *objdir, int local) { struct strbuf path = STRBUF_INIT; size_t dirnamelen; @@ -888,10 +889,10 @@ void prepare_packed_git(void) if (the_repository->objects.packed_git_initialized) return; - prepare_packed_git_one(get_object_directory(), 1); + prepare_packed_git_one(the_repository, get_object_directory(), 1); prepare_alt_odb(the_repository); for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) - prepare_packed_git_one(alt->path, 0); + prepare_packed_git_one(the_repository, alt->path, 0); rearrange_packed_git(the_repository); prepare_packed_git_mru(the_repository); the_repository->objects.packed_git_initialized = 1; -- 2.16.1.435.g8f24da2e1a
[PATCH 32/44] sha1_file: allow sha1_loose_object_info to handle arbitrary repositories
From: Jonathan NiederSigned-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- sha1_file.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index c5a8b00aed..7066d4c9ce 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1149,10 +1149,9 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep) return parse_sha1_header_extended(hdr, , 0); } -#define sha1_loose_object_info(r, s, o, f) sha1_loose_object_info_##r(s, o, f) -static int sha1_loose_object_info_the_repository(const unsigned char *sha1, -struct object_info *oi, -int flags) +static int sha1_loose_object_info(struct repository *r, + const unsigned char *sha1, + struct object_info *oi, int flags) { int status = 0; unsigned long mapsize; @@ -1176,14 +1175,14 @@ static int sha1_loose_object_info_the_repository(const unsigned char *sha1, if (!oi->typep && !oi->typename && !oi->sizep && !oi->contentp) { const char *path; struct stat st; - if (stat_sha1_file(the_repository, sha1, , ) < 0) + if (stat_sha1_file(r, sha1, , ) < 0) return -1; if (oi->disk_sizep) *oi->disk_sizep = st.st_size; return 0; } - map = map_sha1_file(the_repository, sha1, ); + map = map_sha1_file(r, sha1, ); if (!map) return -1; -- 2.16.1.435.g8f24da2e1a
[PATCH 27/44] sha1_file: allow sha1_file_name to handle arbitrary repositories
From: Stefan BellerSigned-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- object-store.h | 3 +-- sha1_file.c| 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/object-store.h b/object-store.h index ad4c7501d7..98622a2b98 100644 --- a/object-store.h +++ b/object-store.h @@ -119,8 +119,7 @@ void raw_object_store_clear(struct raw_object_store *o); * Put in `buf` the name of the file in the local object database that * would be used to store a loose object with the specified sha1. */ -#define sha1_file_name(r, b, s) sha1_file_name_##r(b, s) -void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1); +void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1); #define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz) void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size); diff --git a/sha1_file.c b/sha1_file.c index ecbf846f12..e04e0587c2 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -323,9 +323,9 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1) } } -void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1) +void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1) { - strbuf_addstr(buf, get_object_directory()); + strbuf_addstr(buf, r->objects.objectdir); strbuf_addch(buf, '/'); fill_sha1_path(buf, sha1); } -- 2.16.1.435.g8f24da2e1a
[PATCH 29/44] sha1_file: allow open_sha1_file to handle arbitrary repositories
From: Stefan BellerSigned-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- sha1_file.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index f2533dd9e4..b3f7656c35 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -895,9 +895,8 @@ static int stat_sha1_file(struct repository *r, const unsigned char *sha1, * Like stat_sha1_file(), but actually open the object and return the * descriptor. See the caveats on the "path" parameter above. */ -#define open_sha1_file(r, s, p) open_sha1_file_##r(s, p) -static int open_sha1_file_the_repository(const unsigned char *sha1, -const char **path) +static int open_sha1_file(struct repository *r, + const unsigned char *sha1, const char **path) { int fd; struct alternate_object_database *alt; @@ -905,7 +904,7 @@ static int open_sha1_file_the_repository(const unsigned char *sha1, static struct strbuf buf = STRBUF_INIT; strbuf_reset(); - sha1_file_name(the_repository, , sha1); + sha1_file_name(r, , sha1); *path = buf.buf; fd = git_open(*path); @@ -913,8 +912,8 @@ static int open_sha1_file_the_repository(const unsigned char *sha1, return fd; most_interesting_errno = errno; - prepare_alt_odb(the_repository); - for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) { + prepare_alt_odb(r); + for (alt = r->objects.alt_odb_list; alt; alt = alt->next) { *path = alt_sha1_path(alt, sha1); fd = git_open(*path); if (fd >= 0) -- 2.16.1.435.g8f24da2e1a
[PATCH 30/44] sha1_file: allow map_sha1_file_1 to handle arbitrary repositories
From: Jonathan NiederSigned-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- sha1_file.c | 8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index b3f7656c35..d4678f8162 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -929,10 +929,8 @@ static int open_sha1_file(struct repository *r, * Map the loose object at "path" if it is not NULL, or the path found by * searching for a loose object named "sha1". */ -#define map_sha1_file_1(r, p, s, si) map_sha1_file_1_##r(p, s, si) -static void *map_sha1_file_1_the_repository(const char *path, - const unsigned char *sha1, - unsigned long *size) +static void *map_sha1_file_1(struct repository *r, const char *path, +const unsigned char *sha1, unsigned long *size) { void *map; int fd; @@ -940,7 +938,7 @@ static void *map_sha1_file_1_the_repository(const char *path, if (path) fd = git_open(path); else - fd = open_sha1_file(the_repository, sha1, ); + fd = open_sha1_file(r, sha1, ); map = NULL; if (fd >= 0) { struct stat st; -- 2.16.1.435.g8f24da2e1a
[PATCH 28/44] sha1_file: allow stat_sha1_file to handle arbitrary repositories
From: Stefan BellerSigned-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- sha1_file.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index e04e0587c2..f2533dd9e4 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -867,23 +867,22 @@ int git_open_cloexec(const char *name, int flags) * Note that it may point to static storage and is only valid until another * call to sha1_file_name(), etc. */ -#define stat_sha1_file(r, s, st, p) stat_sha1_file_##r(s, st, p) -static int stat_sha1_file_the_repository(const unsigned char *sha1, -struct stat *st, const char **path) +static int stat_sha1_file(struct repository *r, const unsigned char *sha1, + struct stat *st, const char **path) { struct alternate_object_database *alt; static struct strbuf buf = STRBUF_INIT; strbuf_reset(); - sha1_file_name(the_repository, , sha1); + sha1_file_name(r, , sha1); *path = buf.buf; if (!lstat(*path, st)) return 0; - prepare_alt_odb(the_repository); + prepare_alt_odb(r); errno = ENOENT; - for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) { + for (alt = r->objects.alt_odb_list; alt; alt = alt->next) { *path = alt_sha1_path(alt, sha1); if (!lstat(*path, st)) return 0; -- 2.16.1.435.g8f24da2e1a
[PATCH 25/44] sha1_file: add repository argument to map_sha1_file
From: Stefan BellerAdd a repository argument to allow map_sha1_file callers to be more specific about which repository to handle. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. As with the previous commits, use a macro to catch callers passing a repository other than the_repository at compile time. While at it, move the declaration to object-store.h, where it should be easier to find. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- cache.h| 1 - object-store.h | 3 +++ sha1_file.c| 4 ++-- streaming.c| 5 - 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/cache.h b/cache.h index cbec0ecd23..720664e394 100644 --- a/cache.h +++ b/cache.h @@ -1242,7 +1242,6 @@ extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned c extern int force_object_loose(const unsigned char *sha1, time_t mtime); extern int git_open_cloexec(const char *name, int flags); #define git_open(name) git_open_cloexec(name, O_RDONLY) -extern void *map_sha1_file(const unsigned char *sha1, unsigned long *size); extern int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz); extern int parse_sha1_header(const char *hdr, unsigned long *sizep); diff --git a/object-store.h b/object-store.h index f09acfbf5b..ad4c7501d7 100644 --- a/object-store.h +++ b/object-store.h @@ -122,4 +122,7 @@ void raw_object_store_clear(struct raw_object_store *o); #define sha1_file_name(r, b, s) sha1_file_name_##r(b, s) void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1); +#define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz) +void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size); + #endif /* OBJECT_STORE_H */ diff --git a/sha1_file.c b/sha1_file.c index 78d5ffe876..536c45589b 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -961,7 +961,7 @@ static void *map_sha1_file_1_the_repository(const char *path, return map; } -void *map_sha1_file(const unsigned char *sha1, unsigned long *size) +void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size) { return map_sha1_file_1(the_repository, NULL, sha1, size); } @@ -1185,7 +1185,7 @@ static int sha1_loose_object_info(const unsigned char *sha1, return 0; } - map = map_sha1_file(sha1, ); + map = map_sha1_file(the_repository, sha1, ); if (!map) return -1; diff --git a/streaming.c b/streaming.c index 5892b50bd8..22d27df55e 100644 --- a/streaming.c +++ b/streaming.c @@ -3,6 +3,8 @@ */ #include "cache.h" #include "streaming.h" +#include "repository.h" +#include "object-store.h" #include "packfile.h" enum input_source { @@ -335,7 +337,8 @@ static struct stream_vtbl loose_vtbl = { static open_method_decl(loose) { - st->u.loose.mapped = map_sha1_file(sha1, >u.loose.mapsize); + st->u.loose.mapped = map_sha1_file(the_repository, + sha1, >u.loose.mapsize); if (!st->u.loose.mapped) return -1; if ((unpack_sha1_header(>z, -- 2.16.1.435.g8f24da2e1a
[PATCH 26/44] sha1_file: add repository argument to sha1_loose_object_info
From: Stefan BellerAdd a repository argument to allow the sha1_loose_object_info caller to be more specific about which repository to act on. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. As with the previous commits, use a macro to catch callers passing a repository other than the_repository at compile time. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- sha1_file.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 536c45589b..ecbf846f12 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1152,9 +1152,10 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep) return parse_sha1_header_extended(hdr, , 0); } -static int sha1_loose_object_info(const unsigned char *sha1, - struct object_info *oi, - int flags) +#define sha1_loose_object_info(r, s, o, f) sha1_loose_object_info_##r(s, o, f) +static int sha1_loose_object_info_the_repository(const unsigned char *sha1, +struct object_info *oi, +int flags) { int status = 0; unsigned long mapsize; @@ -1273,7 +1274,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi, break; /* Most likely it's a loose object. */ - if (!sha1_loose_object_info(real, oi, flags)) + if (!sha1_loose_object_info(the_repository, real, oi, flags)) return 0; /* Not a loose object; someone else may have just packed it. */ -- 2.16.1.435.g8f24da2e1a
[PATCH 21/44] sha1_file: add repository argument to sha1_file_name
From: Stefan BellerAdd a repository argument to allow sha1_file_name callers to be more specific about which repository to handle. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. As with the previous commits, use a macro to catch callers passing a repository other than the_repository at compile time. While at it, move the declaration to object-store.h, where it should be easier to find. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- cache.h| 6 -- http-walker.c | 3 ++- http.c | 5 ++--- object-store.h | 7 +++ sha1_file.c| 10 +- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/cache.h b/cache.h index d3429a0d48..cbec0ecd23 100644 --- a/cache.h +++ b/cache.h @@ -961,12 +961,6 @@ extern void check_repository_format(void); #define DATA_CHANGED0x0020 #define TYPE_CHANGED0x0040 -/* - * Put in `buf` the name of the file in the local object database that - * would be used to store a loose object with the specified sha1. - */ -extern void sha1_file_name(struct strbuf *buf, const unsigned char *sha1); - /* * Return an abbreviated sha1 unique within this repository's object database. * The result will be at least `len` characters long, and will be NUL diff --git a/http-walker.c b/http-walker.c index 07c2b1af82..2c33969123 100644 --- a/http-walker.c +++ b/http-walker.c @@ -1,4 +1,5 @@ #include "cache.h" +#include "repository.h" #include "commit.h" #include "walker.h" #include "http.h" @@ -545,7 +546,7 @@ static int fetch_object(struct walker *walker, unsigned char *sha1) ret = error("File %s has bad hash", hex); } else if (req->rename < 0) { struct strbuf buf = STRBUF_INIT; - sha1_file_name(, req->sha1); + sha1_file_name(the_repository, , req->sha1); ret = error("unable to write sha1 filename %s", buf.buf); strbuf_release(); } diff --git a/http.c b/http.c index 31755023a4..df9dbea59c 100644 --- a/http.c +++ b/http.c @@ -2246,7 +2246,7 @@ struct http_object_request *new_http_object_request(const char *base_url, hashcpy(freq->sha1, sha1); freq->localfile = -1; - sha1_file_name(, sha1); + sha1_file_name(the_repository, , sha1); snprintf(freq->tmpfile, sizeof(freq->tmpfile), "%s.temp", filename.buf); @@ -2395,8 +2395,7 @@ int finish_http_object_request(struct http_object_request *freq) unlink_or_warn(freq->tmpfile); return -1; } - - sha1_file_name(, freq->sha1); + sha1_file_name(the_repository, , freq->sha1); freq->rename = finalize_object_file(freq->tmpfile, filename.buf); strbuf_release(); diff --git a/object-store.h b/object-store.h index 141455b5b2..f09acfbf5b 100644 --- a/object-store.h +++ b/object-store.h @@ -115,4 +115,11 @@ struct raw_object_store { void raw_object_store_init(struct raw_object_store *o); void raw_object_store_clear(struct raw_object_store *o); +/* + * Put in `buf` the name of the file in the local object database that + * would be used to store a loose object with the specified sha1. + */ +#define sha1_file_name(r, b, s) sha1_file_name_##r(b, s) +void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1); + #endif /* OBJECT_STORE_H */ diff --git a/sha1_file.c b/sha1_file.c index a3e4ef4253..e06d62a451 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -323,7 +323,7 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1) } } -void sha1_file_name(struct strbuf *buf, const unsigned char *sha1) +void sha1_file_name_the_repository(struct strbuf *buf, const unsigned char *sha1) { strbuf_addstr(buf, get_object_directory()); strbuf_addch(buf, '/'); @@ -713,7 +713,7 @@ static int check_and_freshen_local(const unsigned char *sha1, int freshen) static struct strbuf buf = STRBUF_INIT; strbuf_reset(); - sha1_file_name(, sha1); + sha1_file_name(the_repository, , sha1); return check_and_freshen_file(buf.buf, freshen); } @@ -874,7 +874,7 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st, static struct strbuf buf = STRBUF_INIT; strbuf_reset(); - sha1_file_name(, sha1); + sha1_file_name(the_repository, , sha1); *path = buf.buf; if (!lstat(*path, st)) @@ -903,7 +903,7 @@ static int open_sha1_file(const unsigned char *sha1, const char **path) static struct strbuf buf = STRBUF_INIT; strbuf_reset(); - sha1_file_name(, sha1); + sha1_file_name(the_repository, , sha1); *path = buf.buf; fd = git_open(*path); @@
[PATCH 14/44] sha1_file: add raw_object_store argument to alt_odb_usable
From: Stefan BellerAdd a raw_object_store to alt_odb_usable to be more specific about which repository to act on. The choice of the repository is delegated to its only caller link_alt_odb_entry. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- sha1_file.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 4c9635dada..77c099dadd 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -346,7 +346,9 @@ static const char *alt_sha1_path(struct alternate_object_database *alt, /* * Return non-zero iff the path is usable as an alternate object database. */ -static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir) +static int alt_odb_usable(struct raw_object_store *o, + struct strbuf *path, + const char *normalized_objdir) { struct alternate_object_database *alt; @@ -362,7 +364,7 @@ static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir) * Prevent the common mistake of listing the same * thing twice, or object directory itself. */ - for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) { + for (alt = o->alt_odb_list; alt; alt = alt->next) { if (!fspathcmp(path->buf, alt->path)) return 0; } @@ -414,7 +416,7 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base, while (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/') strbuf_setlen(, pathbuf.len - 1); - if (!alt_odb_usable(, normalized_objdir)) { + if (!alt_odb_usable(_repository->objects, , normalized_objdir)) { strbuf_release(); return -1; } -- 2.16.1.435.g8f24da2e1a
[PATCH 23/44] sha1_file: add repository argument to open_sha1_file
From: Stefan BellerAdd a repository argument to allow the open_sha1_file caller to be more specific about which repository to act on. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. As with the previous commits, use a macro to catch callers passing a repository other than the_repository at compile time. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- sha1_file.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 7b640cca28..d4298805e3 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -896,7 +896,9 @@ static int stat_sha1_file_the_repository(const unsigned char *sha1, * Like stat_sha1_file(), but actually open the object and return the * descriptor. See the caveats on the "path" parameter above. */ -static int open_sha1_file(const unsigned char *sha1, const char **path) +#define open_sha1_file(r, s, p) open_sha1_file_##r(s, p) +static int open_sha1_file_the_repository(const unsigned char *sha1, +const char **path) { int fd; struct alternate_object_database *alt; @@ -939,7 +941,7 @@ static void *map_sha1_file_1(const char *path, if (path) fd = git_open(path); else - fd = open_sha1_file(sha1, ); + fd = open_sha1_file(the_repository, sha1, ); map = NULL; if (fd >= 0) { struct stat st; -- 2.16.1.435.g8f24da2e1a
[PATCH 19/44] sha1_file: allow link_alt_odb_entries to handle arbitrary repositories
From: Stefan BellerActually this also allows read_info_alternates and link_alt_odb_entry to handle arbitrary repositories, but link_alt_odb_entries is the most interesting function in this set of functions, hence the commit subject. These functions span a strongly connected component in the function graph, i.e. the recursive call chain might look like -> link_alt_odb_entries -> link_alt_odb_entry -> read_info_alternates -> link_alt_odb_entries That is why we need to convert all these functions at the same time. Signed-off-by: Jonathan Nieder Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- object-store.h | 4 sha1_file.c| 36 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/object-store.h b/object-store.h index 3d0f8a87cb..20ba136c1f 100644 --- a/object-store.h +++ b/object-store.h @@ -18,6 +18,10 @@ struct alternate_object_database { char loose_objects_subdir_seen[256]; struct oid_array loose_objects_cache; + /* +* Path to the alternative object store. If this is a relative path, +* it is relative to the current working directory. +*/ char path[FLEX_ARRAY]; }; #define prepare_alt_odb(r) prepare_alt_odb_##r() diff --git a/sha1_file.c b/sha1_file.c index 027e0f3741..f34eb69e39 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -390,11 +390,10 @@ static int alt_odb_usable(struct raw_object_store *o, * SHA1, an extra slash for the first level indirection, and the * terminating NUL. */ -#define read_info_alternates(r, rb, d) read_info_alternates_##r(rb, d) -static void read_info_alternates_the_repository(const char *relative_base, - int depth); -#define link_alt_odb_entry(r, e, rb, d, n) link_alt_odb_entry_##r(e, rb, d, n) -static int link_alt_odb_entry_the_repository(const char *entry, +static void read_info_alternates(struct repository *r, +const char *relative_base, +int depth); +static int link_alt_odb_entry(struct repository *r, const char *entry, const char *relative_base, int depth, const char *normalized_objdir) { struct alternate_object_database *ent; @@ -420,7 +419,7 @@ static int link_alt_odb_entry_the_repository(const char *entry, while (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/') strbuf_setlen(, pathbuf.len - 1); - if (!alt_odb_usable(_repository->objects, , normalized_objdir)) { + if (!alt_odb_usable(>objects, , normalized_objdir)) { strbuf_release(); return -1; } @@ -428,12 +427,12 @@ static int link_alt_odb_entry_the_repository(const char *entry, ent = alloc_alt_odb(pathbuf.buf); /* add the alternate entry */ - *the_repository->objects.alt_odb_tail = ent; - the_repository->objects.alt_odb_tail = &(ent->next); + *r->objects.alt_odb_tail = ent; + r->objects.alt_odb_tail = &(ent->next); ent->next = NULL; /* recursively add alternates */ - read_info_alternates(the_repository, pathbuf.buf, depth + 1); + read_info_alternates(r, pathbuf.buf, depth + 1); strbuf_release(); return 0; @@ -468,12 +467,8 @@ static const char *parse_alt_odb_entry(const char *string, return end; } -#define link_alt_odb_entries(r, a, s, rb, d) \ - link_alt_odb_entries_##r(a, s, rb, d) -static void link_alt_odb_entries_the_repository(const char *alt, - int sep, - const char *relative_base, - int depth) +static void link_alt_odb_entries(struct repository *r, const char *alt, +int sep, const char *relative_base, int depth) { struct strbuf objdirbuf = STRBUF_INIT; struct strbuf entry = STRBUF_INIT; @@ -487,7 +482,7 @@ static void link_alt_odb_entries_the_repository(const char *alt, return; } - strbuf_add_absolute_path(, get_object_directory()); + strbuf_add_absolute_path(, r->objects.objectdir); if (strbuf_normalize_path() < 0) die("unable to normalize object directory: %s", objdirbuf.buf); @@ -496,15 +491,16 @@ static void link_alt_odb_entries_the_repository(const char *alt, alt = parse_alt_odb_entry(alt, sep, ); if (!entry.len) continue; - link_alt_odb_entry(the_repository, entry.buf, + link_alt_odb_entry(r, entry.buf, relative_base, depth, objdirbuf.buf); } strbuf_release(); strbuf_release(); } -static
[PATCH 15/44] sha1_file: add repository argument to link_alt_odb_entry
From: Stefan BellerAdd a repository argument to allow the link_alt_odb_entry caller to be more specific about which repository to act on. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. Since the implementation does not yet work with other repositories, use a wrapper macro to enforce that the caller passes in the_repository as the first argument. It would be more appealing to use BUILD_ASSERT_OR_ZERO to enforce this, but that doesn't work because it requires a compile-time constant and common compilers like gcc 4.8.4 do not consider "r == the_repository" a compile-time constant. This and the following three patches add repository arguments to link_alt_odb_entry, read_info_alternates, link_alt_odb_entries and prepare_alt_odb. Three out of the four functions are found in a recursive call chain, calling each other, and one of them accesses the repositories `objectdir` (which was migrated; it was an obvious choice) and `ignore_env` (which we need to keep in the repository struct for clarify); hence we will pass through the repository unlike just the object store object + the ignore_env flag. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- sha1_file.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 77c099dadd..2ee5fe6ba3 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -390,8 +390,9 @@ static int alt_odb_usable(struct raw_object_store *o, * terminating NUL. */ static void read_info_alternates(const char * relative_base, int depth); -static int link_alt_odb_entry(const char *entry, const char *relative_base, - int depth, const char *normalized_objdir) +#define link_alt_odb_entry(r, e, rb, d, n) link_alt_odb_entry_##r(e, rb, d, n) +static int link_alt_odb_entry_the_repository(const char *entry, + const char *relative_base, int depth, const char *normalized_objdir) { struct alternate_object_database *ent; struct strbuf pathbuf = STRBUF_INIT; @@ -488,7 +489,8 @@ static void link_alt_odb_entries(const char *alt, int sep, alt = parse_alt_odb_entry(alt, sep, ); if (!entry.len) continue; - link_alt_odb_entry(entry.buf, relative_base, depth, objdirbuf.buf); + link_alt_odb_entry(the_repository, entry.buf, + relative_base, depth, objdirbuf.buf); } strbuf_release(); strbuf_release(); -- 2.16.1.435.g8f24da2e1a
[PATCH 18/44] sha1_file: add repository argument to prepare_alt_odb
From: Stefan BellerSee previous patch for explanation. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- builtin/fsck.c | 2 +- object-store.h | 3 ++- packfile.c | 2 +- sha1_file.c| 13 +++-- sha1_name.c| 2 +- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/builtin/fsck.c b/builtin/fsck.c index 7aca9699f6..b0abba6e04 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -716,7 +716,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) } else { fsck_object_dir(get_object_directory()); - prepare_alt_odb(); + prepare_alt_odb(the_repository); for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) fsck_object_dir(alt->path); diff --git a/object-store.h b/object-store.h index 56ed4bd9e9..3d0f8a87cb 100644 --- a/object-store.h +++ b/object-store.h @@ -20,7 +20,8 @@ struct alternate_object_database { char path[FLEX_ARRAY]; }; -void prepare_alt_odb(void); +#define prepare_alt_odb(r) prepare_alt_odb_##r() +void prepare_alt_odb_the_repository(void); char *compute_alternate_path(const char *path, struct strbuf *err); typedef int alt_odb_fn(struct alternate_object_database *, void *); int foreach_alt_odb(alt_odb_fn, void*); diff --git a/packfile.c b/packfile.c index ce4cd7d5c9..a0842521e5 100644 --- a/packfile.c +++ b/packfile.c @@ -889,7 +889,7 @@ void prepare_packed_git(void) if (the_repository->objects.packed_git_initialized) return; prepare_packed_git_one(get_object_directory(), 1); - prepare_alt_odb(); + prepare_alt_odb(the_repository); for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) prepare_packed_git_one(alt->path, 0); rearrange_packed_git(); diff --git a/sha1_file.c b/sha1_file.c index 4f9c07b547..027e0f3741 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -23,6 +23,7 @@ #include "sha1-lookup.h" #include "bulk-checkin.h" #include "repository.h" +#include "object-store.h" #include "streaming.h" #include "dir.h" #include "list.h" @@ -581,7 +582,7 @@ void add_to_alternates_memory(const char *reference) * Make sure alternates are initialized, or else our entry may be * overwritten when they are. */ - prepare_alt_odb(); + prepare_alt_odb(the_repository); link_alt_odb_entries(the_repository, reference, '\n', NULL, 0); @@ -667,7 +668,7 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb) struct alternate_object_database *ent; int r = 0; - prepare_alt_odb(); + prepare_alt_odb(the_repository); for (ent = the_repository->objects.alt_odb_list; ent; ent = ent->next) { r = fn(ent, cb); if (r) @@ -676,7 +677,7 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb) return r; } -void prepare_alt_odb(void) +void prepare_alt_odb_the_repository(void) { if (the_repository->objects.alt_odb_tail) return; @@ -726,7 +727,7 @@ static int check_and_freshen_local(const unsigned char *sha1, int freshen) static int check_and_freshen_nonlocal(const unsigned char *sha1, int freshen) { struct alternate_object_database *alt; - prepare_alt_odb(); + prepare_alt_odb(the_repository); for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) { const char *path = alt_sha1_path(alt, sha1); if (check_and_freshen_file(path, freshen)) @@ -885,7 +886,7 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st, if (!lstat(*path, st)) return 0; - prepare_alt_odb(); + prepare_alt_odb(the_repository); errno = ENOENT; for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) { *path = alt_sha1_path(alt, sha1); @@ -916,7 +917,7 @@ static int open_sha1_file(const unsigned char *sha1, const char **path) return fd; most_interesting_errno = errno; - prepare_alt_odb(); + prepare_alt_odb(the_repository); for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) { *path = alt_sha1_path(alt, sha1); fd = git_open(*path); diff --git a/sha1_name.c b/sha1_name.c index bd4d7352ce..2065be90d2 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -353,7 +353,7 @@ static int init_object_disambiguation(const char *name, int len, ds->len = len; ds->hex_pfx[len] = '\0'; - prepare_alt_odb(); + prepare_alt_odb(the_repository); return 0; } -- 2.16.1.435.g8f24da2e1a
[PATCH 17/44] sha1_file: add repository argument to link_alt_odb_entries
From: Stefan BellerSee previous patch for explanation. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Nguyễn Thái Ngọc Duy --- sha1_file.c | 18 -- 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 175ea58686..4f9c07b547 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -467,8 +467,12 @@ static const char *parse_alt_odb_entry(const char *string, return end; } -static void link_alt_odb_entries(const char *alt, int sep, -const char *relative_base, int depth) +#define link_alt_odb_entries(r, a, s, rb, d) \ + link_alt_odb_entries_##r(a, s, rb, d) +static void link_alt_odb_entries_the_repository(const char *alt, + int sep, + const char *relative_base, + int depth) { struct strbuf objdirbuf = STRBUF_INIT; struct strbuf entry = STRBUF_INIT; @@ -511,7 +515,7 @@ static void read_info_alternates_the_repository(const char *relative_base, return; } - link_alt_odb_entries(buf.buf, '\n', relative_base, depth); + link_alt_odb_entries(the_repository, buf.buf, '\n', relative_base, depth); strbuf_release(); free(path); } @@ -565,7 +569,8 @@ void add_to_alternates_file(const char *reference) if (commit_lock_file()) die_errno("unable to move new alternates file into place"); if (the_repository->objects.alt_odb_tail) - link_alt_odb_entries(reference, '\n', NULL, 0); + link_alt_odb_entries(the_repository, reference, +'\n', NULL, 0); } free(alts); } @@ -578,7 +583,8 @@ void add_to_alternates_memory(const char *reference) */ prepare_alt_odb(); - link_alt_odb_entries(reference, '\n', NULL, 0); + link_alt_odb_entries(the_repository, reference, +'\n', NULL, 0); } /* @@ -677,7 +683,7 @@ void prepare_alt_odb(void) the_repository->objects.alt_odb_tail = _repository->objects.alt_odb_list; - link_alt_odb_entries(the_repository->objects.alternate_db, + link_alt_odb_entries(the_repository, the_repository->objects.alternate_db, PATH_SEP, NULL, 0); read_info_alternates(the_repository, get_object_directory(), 0); -- 2.16.1.435.g8f24da2e1a
[PATCH 22/44] sha1_file: add repository argument to stat_sha1_file
From: Stefan BellerAdd a repository argument to allow the stat_sha1_file caller to be more specific about which repository to act on. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. As with the previous commits, use a macro to catch callers passing a repository other than the_repository at compile time. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- sha1_file.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index e06d62a451..7b640cca28 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -867,8 +867,9 @@ int git_open_cloexec(const char *name, int flags) * Note that it may point to static storage and is only valid until another * call to sha1_file_name(), etc. */ -static int stat_sha1_file(const unsigned char *sha1, struct stat *st, - const char **path) +#define stat_sha1_file(r, s, st, p) stat_sha1_file_##r(s, st, p) +static int stat_sha1_file_the_repository(const unsigned char *sha1, +struct stat *st, const char **path) { struct alternate_object_database *alt; static struct strbuf buf = STRBUF_INIT; @@ -1174,7 +1175,7 @@ static int sha1_loose_object_info(const unsigned char *sha1, if (!oi->typep && !oi->typename && !oi->sizep && !oi->contentp) { const char *path; struct stat st; - if (stat_sha1_file(sha1, , ) < 0) + if (stat_sha1_file(the_repository, sha1, , ) < 0) return -1; if (oi->disk_sizep) *oi->disk_sizep = st.st_size; @@ -1388,7 +1389,7 @@ void *read_sha1_file_extended(const unsigned char *sha1, die("replacement %s not found for %s", sha1_to_hex(repl), sha1_to_hex(sha1)); - if (!stat_sha1_file(repl, , )) + if (!stat_sha1_file(the_repository, repl, , )) die("loose object %s (stored in %s) is corrupt", sha1_to_hex(repl), path); -- 2.16.1.435.g8f24da2e1a
[PATCH 16/44] sha1_file: add repository argument to read_info_alternates
From: Stefan BellerSee previous patch for explanation. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- sha1_file.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 2ee5fe6ba3..175ea58686 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -389,7 +389,9 @@ static int alt_odb_usable(struct raw_object_store *o, * SHA1, an extra slash for the first level indirection, and the * terminating NUL. */ -static void read_info_alternates(const char * relative_base, int depth); +#define read_info_alternates(r, rb, d) read_info_alternates_##r(rb, d) +static void read_info_alternates_the_repository(const char *relative_base, + int depth); #define link_alt_odb_entry(r, e, rb, d, n) link_alt_odb_entry_##r(e, rb, d, n) static int link_alt_odb_entry_the_repository(const char *entry, const char *relative_base, int depth, const char *normalized_objdir) @@ -430,7 +432,7 @@ static int link_alt_odb_entry_the_repository(const char *entry, ent->next = NULL; /* recursively add alternates */ - read_info_alternates(pathbuf.buf, depth + 1); + read_info_alternates(the_repository, pathbuf.buf, depth + 1); strbuf_release(); return 0; @@ -496,7 +498,8 @@ static void link_alt_odb_entries(const char *alt, int sep, strbuf_release(); } -static void read_info_alternates(const char * relative_base, int depth) +static void read_info_alternates_the_repository(const char *relative_base, + int depth) { char *path; struct strbuf buf = STRBUF_INIT; @@ -677,7 +680,7 @@ void prepare_alt_odb(void) link_alt_odb_entries(the_repository->objects.alternate_db, PATH_SEP, NULL, 0); - read_info_alternates(get_object_directory(), 0); + read_info_alternates(the_repository, get_object_directory(), 0); } /* Returns 1 if we have successfully freshened the file, 0 otherwise. */ -- 2.16.1.435.g8f24da2e1a
[PATCH 20/44] sha1_file: allow prepare_alt_odb to handle arbitrary repositories
From: Stefan BellerSigned-off-by: Stefan Beller Signed-off-by: Nguyễn Thái Ngọc Duy --- object-store.h | 3 +-- sha1_file.c| 12 +--- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/object-store.h b/object-store.h index 20ba136c1f..141455b5b2 100644 --- a/object-store.h +++ b/object-store.h @@ -24,8 +24,7 @@ struct alternate_object_database { */ char path[FLEX_ARRAY]; }; -#define prepare_alt_odb(r) prepare_alt_odb_##r() -void prepare_alt_odb_the_repository(void); +void prepare_alt_odb(struct repository *r); char *compute_alternate_path(const char *path, struct strbuf *err); typedef int alt_odb_fn(struct alternate_object_database *, void *); int foreach_alt_odb(alt_odb_fn, void*); diff --git a/sha1_file.c b/sha1_file.c index f34eb69e39..a3e4ef4253 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -673,17 +673,15 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb) return r; } -void prepare_alt_odb_the_repository(void) +void prepare_alt_odb(struct repository *r) { - if (the_repository->objects.alt_odb_tail) + if (r->objects.alt_odb_tail) return; - the_repository->objects.alt_odb_tail = - _repository->objects.alt_odb_list; - link_alt_odb_entries(the_repository, the_repository->objects.alternate_db, -PATH_SEP, NULL, 0); + r->objects.alt_odb_tail = >objects.alt_odb_list; + link_alt_odb_entries(r, r->objects.alternate_db, PATH_SEP, NULL, 0); - read_info_alternates(the_repository, get_object_directory(), 0); + read_info_alternates(r, r->objects.objectdir, 0); } /* Returns 1 if we have successfully freshened the file, 0 otherwise. */ -- 2.16.1.435.g8f24da2e1a
[PATCH 24/44] sha1_file: add repository argument to map_sha1_file_1
From: Stefan BellerAdd a repository argument to allow the map_sha1_file_1 caller to be more specific about which repository to act on. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. As with the previous commits, use a macro to catch callers passing a repository other than the_repository at compile time. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- sha1_file.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index d4298805e3..78d5ffe876 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -931,9 +931,10 @@ static int open_sha1_file_the_repository(const unsigned char *sha1, * Map the loose object at "path" if it is not NULL, or the path found by * searching for a loose object named "sha1". */ -static void *map_sha1_file_1(const char *path, -const unsigned char *sha1, -unsigned long *size) +#define map_sha1_file_1(r, p, s, si) map_sha1_file_1_##r(p, s, si) +static void *map_sha1_file_1_the_repository(const char *path, + const unsigned char *sha1, + unsigned long *size) { void *map; int fd; @@ -962,7 +963,7 @@ static void *map_sha1_file_1(const char *path, void *map_sha1_file(const unsigned char *sha1, unsigned long *size) { - return map_sha1_file_1(NULL, sha1, size); + return map_sha1_file_1(the_repository, NULL, sha1, size); } static int unpack_sha1_short_header(git_zstream *stream, @@ -2192,7 +2193,7 @@ int read_loose_object(const char *path, *contents = NULL; - map = map_sha1_file_1(path, NULL, ); + map = map_sha1_file_1(the_repository, path, NULL, ); if (!map) { error_errno("unable to mmap %s", path); goto out; -- 2.16.1.435.g8f24da2e1a
[PATCH 05/44] repository: delete ignore_env member
This variable was added because the repo_set_gitdir() was created to cover both submodule and main repos, but these two are initialized a bit differently so ignore_env == 0 means main repo, while ignore_env != 0 is submodules. Since the difference part (env variables) has been moved out of repo_set_gitdir(), this function works the same way for both repo types and ignore_env is not needed anymore. Signed-off-by: Nguyễn Thái Ngọc Duy--- repository.c | 2 -- repository.h | 9 - 2 files changed, 11 deletions(-) diff --git a/repository.c b/repository.c index 04d85a2869..62f52f47fc 100644 --- a/repository.c +++ b/repository.c @@ -140,8 +140,6 @@ static int repo_init(struct repository *repo, struct repository_format format; memset(repo, 0, sizeof(*repo)); - repo->ignore_env = 1; - if (repo_init_gitdir(repo, gitdir)) goto error; diff --git a/repository.h b/repository.h index 2bfbf762f3..e7127baffb 100644 --- a/repository.h +++ b/repository.h @@ -75,15 +75,6 @@ struct repository { const struct git_hash_algo *hash_algo; /* Configurations */ - /* -* Bit used during initialization to indicate if repository state (like -* the location of the 'objectdir') should be read from the -* environment. By default this bit will be set at the begining of -* 'repo_init()' so that all repositories will ignore the environment. -* The exception to this is 'the_repository', which doesn't go through -* the normal 'repo_init()' process. -*/ - unsigned ignore_env:1; /* Indicate if a repository has a different 'commondir' from 'gitdir' */ unsigned different_commondir:1; -- 2.16.1.435.g8f24da2e1a
[PATCH 04/44] sha1_file.c: move delayed getenv(altdb) back to setup_git_env()
getenv() is supposed to work on the main repository only. This delayed getenv() code in sha1_file.c makes it more difficult to convert sha1_file.c to a generic object store that could be used by both submodule and main repositories. Move the getenv() back in setup_git_env() where other env vars are also fetched. Signed-off-by: Nguyễn Thái Ngọc Duy--- environment.c | 1 + repository.c | 3 +++ repository.h | 4 sha1_file.c | 6 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/environment.c b/environment.c index da3f7daa09..a5eaa97fb1 100644 --- a/environment.c +++ b/environment.c @@ -174,6 +174,7 @@ void setup_git_env(const char *git_dir) args.object_dir = getenv_safe(_free, DB_ENVIRONMENT); args.graft_file = getenv_safe(_free, GRAFT_ENVIRONMENT); args.index_file = getenv_safe(_free, INDEX_ENVIRONMENT); + args.alternate_db = getenv_safe(_free, ALTERNATE_DB_ENVIRONMENT); repo_set_gitdir(the_repository, git_dir, ); argv_array_clear(_free); diff --git a/repository.c b/repository.c index e65f4138a7..04d85a2869 100644 --- a/repository.c +++ b/repository.c @@ -60,6 +60,8 @@ void repo_set_gitdir(struct repository *repo, repo_set_commondir(repo, o->commondir); expand_base_dir(>objectdir, o->object_dir, repo->commondir, "objects"); + free(repo->alternate_db); + repo->alternate_db = xstrdup_or_null(o->alternate_db); expand_base_dir(>graft_file, o->graft_file, repo->commondir, "info/grafts"); expand_base_dir(>index_file, o->index_file, @@ -215,6 +217,7 @@ void repo_clear(struct repository *repo) FREE_AND_NULL(repo->gitdir); FREE_AND_NULL(repo->commondir); FREE_AND_NULL(repo->objectdir); + FREE_AND_NULL(repo->alternate_db); FREE_AND_NULL(repo->graft_file); FREE_AND_NULL(repo->index_file); FREE_AND_NULL(repo->worktree); diff --git a/repository.h b/repository.h index 84aeac2825..2bfbf762f3 100644 --- a/repository.h +++ b/repository.h @@ -26,6 +26,9 @@ struct repository { */ char *objectdir; + /* Path to extra alternate object database if not NULL */ + char *alternate_db; + /* * Path to the repository's graft file. * Cannot be NULL after initialization. @@ -93,6 +96,7 @@ struct set_gitdir_args { const char *object_dir; const char *graft_file; const char *index_file; + const char *alternate_db; }; extern void repo_set_gitdir(struct repository *repo, diff --git a/sha1_file.c b/sha1_file.c index 831d9e7343..4af422e3cf 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -667,15 +667,11 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb) void prepare_alt_odb(void) { - const char *alt; - if (alt_odb_tail) return; - alt = getenv(ALTERNATE_DB_ENVIRONMENT); - alt_odb_tail = _odb_list; - link_alt_odb_entries(alt, PATH_SEP, NULL, 0); + link_alt_odb_entries(the_repository->alternate_db, PATH_SEP, NULL, 0); read_info_alternates(get_object_directory(), 0); } -- 2.16.1.435.g8f24da2e1a
[PATCH 10/44] object-store: move packed_git and packed_git_mru to object store
From: Stefan BellerIn a process with multiple repositories open, packfile accessors should be associated to a single repository and not shared globally. Move packed_git and packed_git_mru into the_repository and adjust callers to reflect this. [nd: while at there, wrap access to these two fields in get_packed_git() and get_packed_git_mru(). This allows us to lazily initialize these fields without caller doing that explicitly] Patch generated by 1. Moving the struct packed_git declaration to object-store.h and packed_git, packed_git_mru globals to struct object_store. 2. Apply the following semantic patch to adjust callers: @@ @@ - packed_git + the_repository->objects.packed_git @@ @@ - packed_git_mru + the_repository->objects.packed_git_mru 3. Applying line wrapping fixes from "make style" to break the resulting long lines. 4. Adding missing #includes of repository.h where needed. 5. As the packfiles are now owned by an objectstore, which is ephemeral unlike globals, we introduce memory leaks. So address them in raw_object_store_clear(). Defer freeing packed_git to the next patch due to the size of this patch. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Nguyễn Thái Ngọc Duy --- builtin/count-objects.c | 5 ++-- builtin/fsck.c | 6 +++-- builtin/gc.c | 3 ++- builtin/pack-objects.c | 20 builtin/pack-redundant.c | 5 ++-- cache.h | 29 fast-import.c| 7 -- http-backend.c | 5 ++-- object-store.h | 28 +++ object.c | 7 ++ pack-bitmap.c| 3 ++- packfile.c | 49 packfile.h | 3 +++ server-info.c| 5 ++-- sha1_name.c | 5 ++-- 15 files changed, 107 insertions(+), 73 deletions(-) diff --git a/builtin/count-objects.c b/builtin/count-objects.c index 33343818c8..5c7c3c6ae3 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -7,6 +7,7 @@ #include "cache.h" #include "config.h" #include "dir.h" +#include "repository.h" #include "builtin.h" #include "parse-options.h" #include "quote.h" @@ -120,9 +121,9 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix) struct strbuf loose_buf = STRBUF_INIT; struct strbuf pack_buf = STRBUF_INIT; struct strbuf garbage_buf = STRBUF_INIT; - if (!packed_git) + if (!get_packed_git(the_repository)) prepare_packed_git(); - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; p = p->next) { if (!p->pack_local) continue; if (open_pack_index(p)) diff --git a/builtin/fsck.c b/builtin/fsck.c index b284a3a74e..7aca9699f6 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -729,7 +729,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) prepare_packed_git(); if (show_progress) { - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; +p = p->next) { if (open_pack_index(p)) continue; total += p->num_objects; @@ -737,7 +738,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) progress = start_progress(_("Checking objects"), total); } - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; +p = p->next) { /* verify gives error messages itself */ if (verify_pack(p, fsck_obj_buffer, progress, count)) diff --git a/builtin/gc.c b/builtin/gc.c index 77fa720bd0..dd30067ac1 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -11,6 +11,7 @@ */ #include "builtin.h" +#include "repository.h" #include "config.h" #include "tempfile.h" #include "lockfile.h" @@ -173,7 +174,7 @@ static int too_many_packs(void) return 0; prepare_packed_git(); - for (cnt = 0, p = packed_git; p; p = p->next) { + for (cnt = 0, p = get_packed_git(the_repository); p; p = p->next) { if (!p->pack_local) continue; if (p->pack_keep) diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 83dcbc9773..0e5fde1d6b
[PATCH 02/44] repository.c: move env-related setup code back to environment.c
It does not make sense that generic repository code contains handling of environment variables, which are specific for the main repository only. Refactor repo_set_gitdir() function to take $GIT_DIR and optionally _all_ other customizable paths. These optional paths can be NULL and will be calculated according to the default directory layout. Note that some dead functions are left behind to reduce diff noise. They will be deleted in the next patch. Signed-off-by: Nguyễn Thái Ngọc Duy--- cache.h | 2 +- environment.c | 30 +++--- repository.c | 58 +++ repository.h | 11 +- setup.c | 3 +-- 5 files changed, 79 insertions(+), 25 deletions(-) diff --git a/cache.h b/cache.h index 9cac7bb518..41ba67cc16 100644 --- a/cache.h +++ b/cache.h @@ -484,7 +484,7 @@ static inline enum object_type object_type(unsigned int mode) */ extern const char * const local_repo_env[]; -extern void setup_git_env(void); +extern void setup_git_env(const char *git_dir); /* * Returns true iff we have a configured git repository (either via diff --git a/environment.c b/environment.c index de8431e01e..da3f7daa09 100644 --- a/environment.c +++ b/environment.c @@ -13,6 +13,7 @@ #include "refs.h" #include "fmt-merge-msg.h" #include "commit.h" +#include "argv-array.h" int trust_executable_bit = 1; int trust_ctime = 1; @@ -147,10 +148,34 @@ static char *expand_namespace(const char *raw_namespace) return strbuf_detach(, NULL); } -void setup_git_env(void) +/* + * Wrapper of getenv() that returns a strdup value. This value is kept + * in argv to be freed later. + */ +static const char *getenv_safe(struct argv_array *argv, const char *name) +{ + const char *value = getenv(name); + + if (!value) + return NULL; + + argv_array_push(argv, value); + return argv->argv[argv->argc - 1]; +} + +void setup_git_env(const char *git_dir) { const char *shallow_file; const char *replace_ref_base; + struct set_gitdir_args args = { NULL }; + struct argv_array to_free = ARGV_ARRAY_INIT; + + args.commondir = getenv_safe(_free, GIT_COMMON_DIR_ENVIRONMENT); + args.object_dir = getenv_safe(_free, DB_ENVIRONMENT); + args.graft_file = getenv_safe(_free, GRAFT_ENVIRONMENT); + args.index_file = getenv_safe(_free, INDEX_ENVIRONMENT); + repo_set_gitdir(the_repository, git_dir, ); + argv_array_clear(_free); if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT)) check_replace_refs = 0; @@ -300,8 +325,7 @@ int set_git_dir(const char *path) { if (setenv(GIT_DIR_ENVIRONMENT, path, 1)) return error("Could not set GIT_DIR to '%s'", path); - repo_set_gitdir(the_repository, path); - setup_git_env(); + setup_git_env(path); return 0; } diff --git a/repository.c b/repository.c index 0eddf28fcd..bb53b54b6d 100644 --- a/repository.c +++ b/repository.c @@ -40,34 +40,55 @@ static int find_common_dir(struct strbuf *sb, const char *gitdir, int fromenv) return get_common_dir_noenv(sb, gitdir); } -static void repo_setup_env(struct repository *repo) +static void expand_base_dir(char **out, const char *in, + const char *base_dir, const char *def_in) +{ + free(*out); + if (in) + *out = xstrdup(in); + else + *out = xstrfmt("%s/%s", base_dir, def_in); +} + +static void repo_set_commondir(struct repository *repo, + const char *commondir) { struct strbuf sb = STRBUF_INIT; - repo->different_commondir = find_common_dir(, repo->gitdir, - !repo->ignore_env); free(repo->commondir); + + if (commondir) { + repo->different_commondir = 1; + repo->commondir = xstrdup(commondir); + return; + } + + repo->different_commondir = get_common_dir_noenv(, repo->gitdir); repo->commondir = strbuf_detach(, NULL); - free(repo->objectdir); - repo->objectdir = git_path_from_env(DB_ENVIRONMENT, repo->commondir, - "objects", !repo->ignore_env); - free(repo->graft_file); - repo->graft_file = git_path_from_env(GRAFT_ENVIRONMENT, repo->commondir, -"info/grafts", !repo->ignore_env); - free(repo->index_file); - repo->index_file = git_path_from_env(INDEX_ENVIRONMENT, repo->gitdir, -"index", !repo->ignore_env); } -void repo_set_gitdir(struct repository *repo, const char *path) +void repo_set_gitdir(struct repository *repo, +const char *root, +const struct set_gitdir_args *o) { - const char *gitfile = read_gitfile(path); + const char *gitfile =
[PATCH 13/44] pack: move approximate object count to object store
From: Stefan BellerThe approximate_object_count() function maintains a rough count of objects in a repository to estimate how long object name abbreviates should be. Object names are scoped to a repository and the appropriate length may differ by repository, so the object count should not be global. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Nguyễn Thái Ngọc Duy --- object-store.h | 8 packfile.c | 11 +-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/object-store.h b/object-store.h index b954396615..56ed4bd9e9 100644 --- a/object-store.h +++ b/object-store.h @@ -93,6 +93,14 @@ struct raw_object_store { struct alternate_object_database *alt_odb_list; struct alternate_object_database **alt_odb_tail; + /* +* A fast, rough count of the number of objects in the repository. +* These two fields are not meant for direct access. Use +* approximate_object_count() instead. +*/ + unsigned long approximate_object_count; + unsigned approximate_object_count_valid : 1; + /* * Whether packed_git has already been populated with this repository's * packs. diff --git a/packfile.c b/packfile.c index caeab0f68c..ce4cd7d5c9 100644 --- a/packfile.c +++ b/packfile.c @@ -802,8 +802,6 @@ static void prepare_packed_git_one(char *objdir, int local) strbuf_release(); } -static int approximate_object_count_valid; - /* * Give a fast, rough count of the number of objects in the repository. This * ignores loose objects completely. If you have a lot of them, then either @@ -813,8 +811,8 @@ static int approximate_object_count_valid; */ unsigned long approximate_object_count(void) { - static unsigned long count; - if (!approximate_object_count_valid) { + if (!the_repository->objects.approximate_object_count_valid) { + unsigned long count; struct packed_git *p; prepare_packed_git(); @@ -824,8 +822,9 @@ unsigned long approximate_object_count(void) continue; count += p->num_objects; } + the_repository->objects.approximate_object_count = count; } - return count; + return the_repository->objects.approximate_object_count; } static void *get_next_packed_git(const void *p) @@ -900,7 +899,7 @@ void prepare_packed_git(void) void reprepare_packed_git(void) { - approximate_object_count_valid = 0; + the_repository->objects.approximate_object_count_valid = 0; the_repository->objects.packed_git_initialized = 0; prepare_packed_git(); } -- 2.16.1.435.g8f24da2e1a
[PATCH 09/44] object-store: free alt_odb_list
From: Stefan BellerFree the memory and reset alt_odb_{list, tail} to NULL. Signed-off-by: Stefan Beller Signed-off-by: Nguyễn Thái Ngọc Duy --- object.c | 18 ++ 1 file changed, 18 insertions(+) diff --git a/object.c b/object.c index e91711dd56..a71ab34e69 100644 --- a/object.c +++ b/object.c @@ -450,8 +450,26 @@ void raw_object_store_init(struct raw_object_store *o) { memset(o, 0, sizeof(*o)); } + +static void free_alt_odb(struct alternate_object_database *alt) +{ + strbuf_release(>scratch); + oid_array_clear(>loose_objects_cache); +} + +static void free_alt_odbs(struct raw_object_store *o) +{ + while (o->alt_odb_list) { + free_alt_odb(o->alt_odb_list); + o->alt_odb_list = o->alt_odb_list->next; + } +} + void raw_object_store_clear(struct raw_object_store *o) { FREE_AND_NULL(o->objectdir); FREE_AND_NULL(o->alternate_db); + + free_alt_odbs(o); + o->alt_odb_tail = NULL; } -- 2.16.1.435.g8f24da2e1a
[PATCH 12/44] pack: move prepare_packed_git_run_once to object store
From: Stefan BellerEach repository's object store can be initialized independently, so they must not share a run_once variable. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Nguyễn Thái Ngọc Duy --- object-store.h | 6 ++ packfile.c | 7 +++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/object-store.h b/object-store.h index 1f3e66a3b8..b954396615 100644 --- a/object-store.h +++ b/object-store.h @@ -92,6 +92,12 @@ struct raw_object_store { struct alternate_object_database *alt_odb_list; struct alternate_object_database **alt_odb_tail; + + /* +* Whether packed_git has already been populated with this repository's +* packs. +*/ + unsigned packed_git_initialized : 1; }; void raw_object_store_init(struct raw_object_store *o); diff --git a/packfile.c b/packfile.c index 1e38334ba2..caeab0f68c 100644 --- a/packfile.c +++ b/packfile.c @@ -883,12 +883,11 @@ static void prepare_packed_git_mru(void) list_add_tail(>mru, _repository->objects.packed_git_mru); } -static int prepare_packed_git_run_once = 0; void prepare_packed_git(void) { struct alternate_object_database *alt; - if (prepare_packed_git_run_once) + if (the_repository->objects.packed_git_initialized) return; prepare_packed_git_one(get_object_directory(), 1); prepare_alt_odb(); @@ -896,13 +895,13 @@ void prepare_packed_git(void) prepare_packed_git_one(alt->path, 0); rearrange_packed_git(); prepare_packed_git_mru(); - prepare_packed_git_run_once = 1; + the_repository->objects.packed_git_initialized = 1; } void reprepare_packed_git(void) { approximate_object_count_valid = 0; - prepare_packed_git_run_once = 0; + the_repository->objects.packed_git_initialized = 0; prepare_packed_git(); } -- 2.16.1.435.g8f24da2e1a
[PATCH 11/44] object-store: close all packs upon clearing the object store
From: Stefan BellerSigned-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- builtin/am.c | 2 +- builtin/clone.c| 2 +- builtin/fetch.c| 2 +- builtin/merge.c| 2 +- builtin/receive-pack.c | 2 +- object.c | 7 +++ packfile.c | 4 ++-- packfile.h | 2 +- 8 files changed, 11 insertions(+), 12 deletions(-) diff --git a/builtin/am.c b/builtin/am.c index 5bdd2d7578..4762a702e3 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1859,7 +1859,7 @@ static void am_run(struct am_state *state, int resume) */ if (!state->rebasing) { am_destroy(state); - close_all_packs(); + close_all_packs(_repository->objects); run_command_v_opt(argv_gc_auto, RUN_GIT_CMD); } } diff --git a/builtin/clone.c b/builtin/clone.c index 101c27a593..13cfaa6488 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -1217,7 +1217,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) transport_disconnect(transport); if (option_dissociate) { - close_all_packs(); + close_all_packs(_repository->objects); dissociate_from_references(); } diff --git a/builtin/fetch.c b/builtin/fetch.c index 8ee998ea2e..4d72efca78 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -1478,7 +1478,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) string_list_clear(, 0); - close_all_packs(); + close_all_packs(_repository->objects); argv_array_pushl(_gc_auto, "gc", "--auto", NULL); if (verbosity < 0) diff --git a/builtin/merge.c b/builtin/merge.c index 30264cfd7c..907ae44ab5 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -411,7 +411,7 @@ static void finish(struct commit *head_commit, * We ignore errors in 'gc --auto', since the * user should see them. */ - close_all_packs(); + close_all_packs(_repository->objects); run_command_v_opt(argv_gc_auto, RUN_GIT_CMD); } } diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index b7ce7c7f52..ac478b7b99 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -2026,7 +2026,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix) proc.git_cmd = 1; proc.argv = argv_gc_auto; - close_all_packs(); + close_all_packs(_repository->objects); if (!start_command()) { if (use_sideband) copy_to_sideband(proc.err, -1, NULL); diff --git a/object.c b/object.c index 83be6b1ecb..60ca76b285 100644 --- a/object.c +++ b/object.c @@ -4,6 +4,7 @@ #include "tree.h" #include "commit.h" #include "tag.h" +#include "packfile.h" static struct object **obj_hash; static int nr_objs, obj_hash_size; @@ -475,8 +476,6 @@ void raw_object_store_clear(struct raw_object_store *o) o->alt_odb_tail = NULL; INIT_LIST_HEAD(>packed_git_mru); - /* -* TODO: call close_all_packs once migrated to -* take an object store argument -*/ + close_all_packs(o); + o->packed_git = NULL; } diff --git a/packfile.c b/packfile.c index d3c4a12ae0..1e38334ba2 100644 --- a/packfile.c +++ b/packfile.c @@ -310,11 +310,11 @@ static void close_pack(struct packed_git *p) close_pack_index(p); } -void close_all_packs(void) +void close_all_packs(struct raw_object_store *o) { struct packed_git *p; - for (p = the_repository->objects.packed_git; p; p = p->next) + for (p = o->packed_git; p; p = p->next) if (p->do_not_close) die("BUG: want to close pack marked 'do-not-close'"); else diff --git a/packfile.h b/packfile.h index 76496226bb..5b1ce00f84 100644 --- a/packfile.h +++ b/packfile.h @@ -66,7 +66,7 @@ extern void close_pack_index(struct packed_git *); extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *); extern void close_pack_windows(struct packed_git *); -extern void close_all_packs(void); +extern void close_all_packs(struct raw_object_store *o); extern void unuse_pack(struct pack_window **); extern void clear_delta_base_cache(void); extern struct packed_git *add_packed_git(const char *path, size_t path_len, int local); -- 2.16.1.435.g8f24da2e1a
[PATCH 00/44] reroll nd/remove-ignore-env.. sb/object-store and sb/packfiles..
On Sat, Mar 3, 2018 at 9:54 AM, Duy Nguyenwrote: > On Thu, Mar 1, 2018 at 2:09 AM, Junio C Hamano wrote: >> Stefan Beller writes: >> >>> On Wed, Feb 28, 2018 at 9:59 AM, Junio C Hamano wrote: Duy Nguyen writes: > Looking at the full-series diff though, it makes me wonder if we > should keep prepare_packed_git() private (i.e. how we initialize the > object store, packfile included, is a private matter). How about > something like this on top? Yup, that looks cleaner. >>> >>> I agree that it looks cleaner. So we plan on just putting >>> it on top of that series? >> >> We tend to avoid "oops, that was wrong and here is a band aid on >> top" for things that are still mushy, so it would be preferrable to >> get it fixed inline, especially if there are more changes to the >> other parts of the series coming. > > I agree with this. Stefan, if you're getting bored with rerolling > refactor patches, I can update this series and send out v2. Since Stefan is traveling, I take this opportunity to reroll it. Unfortunately, I think the fix should go in 46cd557bd9 (object-store: move packed_git and packed_git_mru to object store - 2018-02-23) where we start removing the global "packed_git". But that's in sb/object-store, so.. I'm rerolling all three 01/44 - 05/44: nd/remove-ignore-env-field This series is moved up top. After this the patch that touch alternate-db in sha1_file.c looks natural because no env is involved anymore I also take this opportunity to introduce a new patch 01/44 to avoid struct initialization that makes it hard to read and update. Later patches are also simplified thanks to this. 06/44 - 32/44: sb/object-store 06/44 is updated to introduce raw_object_store_init() instead of RAW_OBJECT_STORE_INIT macro. This function is now used to initialize both main repo and submodule ones. 10/44 (moving "packed_git") also introduces two new access wrapper get_packed_git() and get_packed_git_mru() 33/44 - 44/44: sb/packfiles-in-repository The only thing new here is 44/44 which makes prepare_packed_git() internal. get_packed_git() and get_packed_git_mru() introduced earlier will call prepare_packed_git() automatically. The whole thing is also available at https://github.com/pclouds/git/tree/ignore-env-object-store-packfiles And interdiff of all three, compared to what is currently in 'pu'. Looks pretty good in my opinon: diff --git a/builtin/count-objects.c b/builtin/count-objects.c index d480301763..ee6ae35244 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -121,9 +121,8 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix) struct strbuf loose_buf = STRBUF_INIT; struct strbuf pack_buf = STRBUF_INIT; struct strbuf garbage_buf = STRBUF_INIT; - if (!the_repository->objects.packed_git) - prepare_packed_git(the_repository); - for (p = the_repository->objects.packed_git; p; p = p->next) { + + for (p = get_packed_git(the_repository); p; p = p->next) { if (!p->pack_local) continue; if (open_pack_index(p)) diff --git a/builtin/fsck.c b/builtin/fsck.c index 030c7fb7a0..9911c52bc8 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -726,10 +726,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) uint32_t total = 0, count = 0; struct progress *progress = NULL; - prepare_packed_git(the_repository); - if (show_progress) { - for (p = the_repository->objects.packed_git; p; + for (p = get_packed_git(the_repository); p; p = p->next) { if (open_pack_index(p)) continue; @@ -738,7 +736,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) progress = start_progress(_("Checking objects"), total); } - for (p = the_repository->objects.packed_git; p; + for (p = get_packed_git(the_repository); p; p = p->next) { /* verify gives error messages itself */ if (verify_pack(p, fsck_obj_buffer, diff --git a/builtin/gc.c b/builtin/gc.c index 80d19c54d5..be63bec09c 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -173,8 +173,7 @@ static int too_many_packs(void) if (gc_auto_pack_limit <= 0) return 0; - prepare_packed_git(the_repository); - for (cnt = 0, p = the_repository->objects.packed_git; p; p = p->next) {
[PATCH 06/44] repository: introduce raw object store field
From: Stefan BellerThe raw object store field will contain any objects needed for access to objects in a given repository. This patch introduces the raw object store and populates it with the `objectdir`, which used to be part of the repository struct. As the struct gains members, we'll also populate the function to clear the memory for these members. In a later we'll introduce a struct object_parser, that will complement the object parsing in a repository struct: The raw object parser is the layer that will provide access to raw object content, while the higher level object parser code will parse raw objects and keeps track of parenthood and other object relationships using 'struct object'. For now only add the lower level to the repository struct. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Nguyễn Thái Ngọc Duy --- builtin/grep.c | 2 +- environment.c | 5 +++-- object-store.h | 18 ++ object.c | 10 ++ path.c | 2 +- repository.c | 14 +- repository.h | 10 -- sha1_file.c| 3 ++- 8 files changed, 48 insertions(+), 16 deletions(-) create mode 100644 object-store.h diff --git a/builtin/grep.c b/builtin/grep.c index 3ca4ac80d8..0f0c195705 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -432,7 +432,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject, * object. */ grep_read_lock(); - add_to_alternates_memory(submodule.objectdir); + add_to_alternates_memory(submodule.objects.objectdir); grep_read_unlock(); if (oid) { diff --git a/environment.c b/environment.c index a5eaa97fb1..c05705e384 100644 --- a/environment.c +++ b/environment.c @@ -14,6 +14,7 @@ #include "fmt-merge-msg.h" #include "commit.h" #include "argv-array.h" +#include "object-store.h" int trust_executable_bit = 1; int trust_ctime = 1; @@ -270,9 +271,9 @@ const char *get_git_work_tree(void) char *get_object_directory(void) { - if (!the_repository->objectdir) + if (!the_repository->objects.objectdir) BUG("git environment hasn't been setup"); - return the_repository->objectdir; + return the_repository->objects.objectdir; } int odb_mkstemp(struct strbuf *template, const char *pattern) diff --git a/object-store.h b/object-store.h new file mode 100644 index 00..69bb5ac065 --- /dev/null +++ b/object-store.h @@ -0,0 +1,18 @@ +#ifndef OBJECT_STORE_H +#define OBJECT_STORE_H + +struct raw_object_store { + /* +* Path to the repository's object store. +* Cannot be NULL after initialization. +*/ + char *objectdir; + + /* Path to extra alternate object database if not NULL */ + char *alternate_db; +}; + +void raw_object_store_init(struct raw_object_store *o); +void raw_object_store_clear(struct raw_object_store *o); + +#endif /* OBJECT_STORE_H */ diff --git a/object.c b/object.c index 9e6f9ff20b..e91711dd56 100644 --- a/object.c +++ b/object.c @@ -445,3 +445,13 @@ void clear_commit_marks_all(unsigned int flags) obj->flags &= ~flags; } } + +void raw_object_store_init(struct raw_object_store *o) +{ + memset(o, 0, sizeof(*o)); +} +void raw_object_store_clear(struct raw_object_store *o) +{ + FREE_AND_NULL(o->objectdir); + FREE_AND_NULL(o->alternate_db); +} diff --git a/path.c b/path.c index da8b655730..81a42d9115 100644 --- a/path.c +++ b/path.c @@ -382,7 +382,7 @@ static void adjust_git_path(const struct repository *repo, strbuf_splice(buf, 0, buf->len, repo->index_file, strlen(repo->index_file)); else if (dir_prefix(base, "objects")) - replace_dir(buf, git_dir_len + 7, repo->objectdir); + replace_dir(buf, git_dir_len + 7, repo->objects.objectdir); else if (git_hooks_path && dir_prefix(base, "hooks")) replace_dir(buf, git_dir_len + 5, git_hooks_path); else if (repo->different_commondir) diff --git a/repository.c b/repository.c index 62f52f47fc..34c0a7f180 100644 --- a/repository.c +++ b/repository.c @@ -1,5 +1,6 @@ #include "cache.h" #include "repository.h" +#include "object-store.h" #include "config.h" #include "submodule-config.h" @@ -12,6 +13,7 @@ void initialize_the_repository(void) the_repository = _repo; the_repo.index = _index; + raw_object_store_init(_repo.objects); repo_set_hash_algo(_repo, GIT_HASH_SHA1); } @@ -58,10 +60,10 @@ void repo_set_gitdir(struct repository *repo, free(old_gitdir); repo_set_commondir(repo, o->commondir); - expand_base_dir(>objectdir, o->object_dir, + expand_base_dir(>objects.objectdir, o->object_dir, repo->commondir, "objects"); - free(repo->alternate_db); -
[PATCH 08/44] object-store: move alt_odb_list and alt_odb_tail to object store
From: Stefan BellerIn a process with multiple repositories open, alternates should be associated to a single repository and not shared globally. Move alt_odb_list and alt_odb_tail into the_repository and adjust callers to reflect this. Now that the alternative object data base is per repository, we're leaking its memory upon freeing a repository. The next patch plugs this hole. No functional change intended. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Nguyễn Thái Ngọc Duy --- builtin/fsck.c | 4 +++- object-store.h | 7 +-- packfile.c | 3 ++- sha1_file.c| 25 - sha1_name.c| 3 ++- 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/builtin/fsck.c b/builtin/fsck.c index 7a8a679d4f..b284a3a74e 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "cache.h" +#include "repository.h" #include "config.h" #include "commit.h" #include "tree.h" @@ -716,7 +717,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) fsck_object_dir(get_object_directory()); prepare_alt_odb(); - for (alt = alt_odb_list; alt; alt = alt->next) + for (alt = the_repository->objects.alt_odb_list; +alt; alt = alt->next) fsck_object_dir(alt->path); if (check_full) { diff --git a/object-store.h b/object-store.h index 505f123976..0ca9233a85 100644 --- a/object-store.h +++ b/object-store.h @@ -1,7 +1,7 @@ #ifndef OBJECT_STORE_H #define OBJECT_STORE_H -extern struct alternate_object_database { +struct alternate_object_database { struct alternate_object_database *next; /* see alt_scratch_buf() */ @@ -19,7 +19,7 @@ extern struct alternate_object_database { struct oid_array loose_objects_cache; char path[FLEX_ARRAY]; -} *alt_odb_list; +}; void prepare_alt_odb(void); char *compute_alternate_path(const char *path, struct strbuf *err); typedef int alt_odb_fn(struct alternate_object_database *, void *); @@ -61,6 +61,9 @@ struct raw_object_store { /* Path to extra alternate object database if not NULL */ char *alternate_db; + + struct alternate_object_database *alt_odb_list; + struct alternate_object_database **alt_odb_tail; }; void raw_object_store_init(struct raw_object_store *o); diff --git a/packfile.c b/packfile.c index 7dbe8739d1..216ea836ee 100644 --- a/packfile.c +++ b/packfile.c @@ -1,6 +1,7 @@ #include "cache.h" #include "list.h" #include "pack.h" +#include "repository.h" #include "dir.h" #include "mergesort.h" #include "packfile.h" @@ -891,7 +892,7 @@ void prepare_packed_git(void) return; prepare_packed_git_one(get_object_directory(), 1); prepare_alt_odb(); - for (alt = alt_odb_list; alt; alt = alt->next) + for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) prepare_packed_git_one(alt->path, 0); rearrange_packed_git(); prepare_packed_git_mru(); diff --git a/sha1_file.c b/sha1_file.c index 792bb21c15..4c9635dada 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -22,6 +22,7 @@ #include "pack-revindex.h" #include "sha1-lookup.h" #include "bulk-checkin.h" +#include "repository.h" #include "streaming.h" #include "dir.h" #include "list.h" @@ -342,9 +343,6 @@ static const char *alt_sha1_path(struct alternate_object_database *alt, return buf->buf; } -struct alternate_object_database *alt_odb_list; -static struct alternate_object_database **alt_odb_tail; - /* * Return non-zero iff the path is usable as an alternate object database. */ @@ -364,7 +362,7 @@ static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir) * Prevent the common mistake of listing the same * thing twice, or object directory itself. */ - for (alt = alt_odb_list; alt; alt = alt->next) { + for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) { if (!fspathcmp(path->buf, alt->path)) return 0; } @@ -424,8 +422,8 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base, ent = alloc_alt_odb(pathbuf.buf); /* add the alternate entry */ - *alt_odb_tail = ent; - alt_odb_tail = &(ent->next); + *the_repository->objects.alt_odb_tail = ent; + the_repository->objects.alt_odb_tail = &(ent->next); ent->next = NULL; /* recursively add alternates */ @@ -559,7 +557,7 @@ void add_to_alternates_file(const char *reference) fprintf_or_die(out, "%s\n", reference); if (commit_lock_file()) die_errno("unable to move new alternates file into place"); - if (alt_odb_tail) + if
[PATCH 07/44] object-store: migrate alternates struct and functions from cache.h
From: Stefan BellerMigrate the struct alternate_object_database and all its related functions to the object store as these functions are easier found in that header. The migration is just a verbatim copy, no need to include the object store header at any C file, because cache.h includes repository.h which in turn includes the object-store.h Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano Signed-off-by: Nguyễn Thái Ngọc Duy --- cache.h| 51 -- object-store.h | 51 ++ 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/cache.h b/cache.h index 41ba67cc16..41530d5d16 100644 --- a/cache.h +++ b/cache.h @@ -1576,57 +1576,6 @@ extern int has_dirs_only_path(const char *name, int len, int prefix_len); extern void schedule_dir_for_removal(const char *name, int len); extern void remove_scheduled_dirs(void); -extern struct alternate_object_database { - struct alternate_object_database *next; - - /* see alt_scratch_buf() */ - struct strbuf scratch; - size_t base_len; - - /* -* Used to store the results of readdir(3) calls when searching -* for unique abbreviated hashes. This cache is never -* invalidated, thus it's racy and not necessarily accurate. -* That's fine for its purpose; don't use it for tasks requiring -* greater accuracy! -*/ - char loose_objects_subdir_seen[256]; - struct oid_array loose_objects_cache; - - char path[FLEX_ARRAY]; -} *alt_odb_list; -extern void prepare_alt_odb(void); -extern char *compute_alternate_path(const char *path, struct strbuf *err); -typedef int alt_odb_fn(struct alternate_object_database *, void *); -extern int foreach_alt_odb(alt_odb_fn, void*); - -/* - * Allocate a "struct alternate_object_database" but do _not_ actually - * add it to the list of alternates. - */ -struct alternate_object_database *alloc_alt_odb(const char *dir); - -/* - * Add the directory to the on-disk alternates file; the new entry will also - * take effect in the current process. - */ -extern void add_to_alternates_file(const char *dir); - -/* - * Add the directory to the in-memory list of alternates (along with any - * recursive alternates it points to), but do not modify the on-disk alternates - * file. - */ -extern void add_to_alternates_memory(const char *dir); - -/* - * Returns a scratch strbuf pre-filled with the alternate object directory, - * including a trailing slash, which can be used to access paths in the - * alternate. Always use this over direct access to alt->scratch, as it - * cleans up any previous use of the scratch buffer. - */ -extern struct strbuf *alt_scratch_buf(struct alternate_object_database *alt); - struct pack_window { struct pack_window *next; unsigned char *base; diff --git a/object-store.h b/object-store.h index 69bb5ac065..505f123976 100644 --- a/object-store.h +++ b/object-store.h @@ -1,6 +1,57 @@ #ifndef OBJECT_STORE_H #define OBJECT_STORE_H +extern struct alternate_object_database { + struct alternate_object_database *next; + + /* see alt_scratch_buf() */ + struct strbuf scratch; + size_t base_len; + + /* +* Used to store the results of readdir(3) calls when searching +* for unique abbreviated hashes. This cache is never +* invalidated, thus it's racy and not necessarily accurate. +* That's fine for its purpose; don't use it for tasks requiring +* greater accuracy! +*/ + char loose_objects_subdir_seen[256]; + struct oid_array loose_objects_cache; + + char path[FLEX_ARRAY]; +} *alt_odb_list; +void prepare_alt_odb(void); +char *compute_alternate_path(const char *path, struct strbuf *err); +typedef int alt_odb_fn(struct alternate_object_database *, void *); +int foreach_alt_odb(alt_odb_fn, void*); + +/* + * Allocate a "struct alternate_object_database" but do _not_ actually + * add it to the list of alternates. + */ +struct alternate_object_database *alloc_alt_odb(const char *dir); + +/* + * Add the directory to the on-disk alternates file; the new entry will also + * take effect in the current process. + */ +void add_to_alternates_file(const char *dir); + +/* + * Add the directory to the in-memory list of alternates (along with any + * recursive alternates it points to), but do not modify the on-disk alternates + * file. + */ +void add_to_alternates_memory(const char *dir); + +/* + * Returns a scratch strbuf pre-filled with the alternate object directory, + * including a trailing slash, which can be used to access paths in the + * alternate. Always use this over direct access to alt->scratch, as it + * cleans up any previous use of the scratch buffer. + */ +struct strbuf *alt_scratch_buf(struct alternate_object_database *alt); + struct
[PATCH 01/44] repository: initialize the_repository in main()
This simplifies initialization of struct repository and anything inside. Easier to read. Easier to add/remove fields. Everything will go through main() common-main.c so this should cover all programs, including t/helper. Signed-off-by: Nguyễn Thái Ngọc Duy--- common-main.c | 2 ++ repository.c | 18 +- repository.h | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/common-main.c b/common-main.c index 6a689007e7..7d716d5a54 100644 --- a/common-main.c +++ b/common-main.c @@ -34,6 +34,8 @@ int main(int argc, const char **argv) git_setup_gettext(); + initialize_the_repository(); + attr_start(); git_extract_argv0_path(argv[0]); diff --git a/repository.c b/repository.c index 4ffbe9bc94..0eddf28fcd 100644 --- a/repository.c +++ b/repository.c @@ -4,10 +4,16 @@ #include "submodule-config.h" /* The main repository */ -static struct repository the_repo = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, _index, _algos[GIT_HASH_SHA1], 0, 0 -}; -struct repository *the_repository = _repo; +static struct repository the_repo; +struct repository *the_repository; + +void initialize_the_repository(void) +{ + the_repository = _repo; + + the_repo.index = _index; + repo_set_hash_algo(_repo, GIT_HASH_SHA1); +} static char *git_path_from_env(const char *envvar, const char *git_dir, const char *path, int fromenv) @@ -128,7 +134,9 @@ static int read_and_verify_repository_format(struct repository_format *format, * Initialize 'repo' based on the provided 'gitdir'. * Return 0 upon success and a non-zero value upon failure. */ -int repo_init(struct repository *repo, const char *gitdir, const char *worktree) +static int repo_init(struct repository *repo, +const char *gitdir, +const char *worktree) { struct repository_format format; memset(repo, 0, sizeof(*repo)); diff --git a/repository.h b/repository.h index 0329e40c7f..40c1c81bdc 100644 --- a/repository.h +++ b/repository.h @@ -91,7 +91,7 @@ extern struct repository *the_repository; extern void repo_set_gitdir(struct repository *repo, const char *path); extern void repo_set_worktree(struct repository *repo, const char *path); extern void repo_set_hash_algo(struct repository *repo, int algo); -extern int repo_init(struct repository *repo, const char *gitdir, const char *worktree); +extern void initialize_the_repository(void); extern int repo_submodule_init(struct repository *submodule, struct repository *superproject, const char *path); -- 2.16.1.435.g8f24da2e1a
[PATCH 03/44] repository.c: delete dead functions
Signed-off-by: Nguyễn Thái Ngọc DuySigned-off-by: Junio C Hamano --- repository.c | 25 - 1 file changed, 25 deletions(-) diff --git a/repository.c b/repository.c index bb53b54b6d..e65f4138a7 100644 --- a/repository.c +++ b/repository.c @@ -15,31 +15,6 @@ void initialize_the_repository(void) repo_set_hash_algo(_repo, GIT_HASH_SHA1); } -static char *git_path_from_env(const char *envvar, const char *git_dir, - const char *path, int fromenv) -{ - if (fromenv) { - const char *value = getenv(envvar); - if (value) - return xstrdup(value); - } - - return xstrfmt("%s/%s", git_dir, path); -} - -static int find_common_dir(struct strbuf *sb, const char *gitdir, int fromenv) -{ - if (fromenv) { - const char *value = getenv(GIT_COMMON_DIR_ENVIRONMENT); - if (value) { - strbuf_addstr(sb, value); - return 1; - } - } - - return get_common_dir_noenv(sb, gitdir); -} - static void expand_base_dir(char **out, const char *in, const char *base_dir, const char *def_in) { -- 2.16.1.435.g8f24da2e1a
Re: Contributor Summit planning
On Sat, Mar 03, 2018 at 05:30:10AM -0500, Jeff King wrote: > As in past years, I plan to run it like an unconference. Attendees are > expected to bring topics for group discussion. Short presentations are > also welcome. We'll put the topics on a whiteboard in the morning, and > pick whichever ones people are interested in. > > Feel free to reply to this thread if you want to make plans or discuss > any proposed topics before the summit. Input or questions from > non-attendees is welcome here. I'll plan to offer two topics: - a round-up of the current state and past year's activities of Git as a member project of Software Freedom Conservancy - some updates on the state of the git-scm.com since my report last year As with last year, I'll try to send a written report to the list for those who aren't at the summit in person. -Peff
Contributor Summit planning
The Git Merge Contributor Summit is scheduled for this coming Wednesday, March 7th, in Barcelona. If you're not registered, there are still one or two slots left for last-minute attendees. Please email me if you're interested. As in past years, I plan to run it like an unconference. Attendees are expected to bring topics for group discussion. Short presentations are also welcome. We'll put the topics on a whiteboard in the morning, and pick whichever ones people are interested in. Feel free to reply to this thread if you want to make plans or discuss any proposed topics before the summit. Input or questions from non-attendees is welcome here. The rest of this email is all logistics for attendees, so if you're not coming, you can stop reading. :) There should be breakfast available in the contributor summit room starting at 9am, so plan to get there around then, mingle and eat, and then we'll start in earnest at 10am. Registration is at the main Git Merge event space (Convent dels Àngels at MACBA), and then our contributor summit space is across the street. So go to the main registration first, and then signs and clueful staff should be able to point you to the contributor summit room. We have the space until 5pm, so we'll go until then or until we run out of stuff to say, whichever comes first. Lunch will be served in the room, and we'll probably take a few informal breaks during the day. After we finish for the day, there are a few other events. Bitbucket is hosting drinks and discussion from 5:30-7:30pm, open to all Git Merge attendees (not just contributor summit people). Details and RSVP at: https://www.bevylabs.com/events/details/bevy-beers-with-bitbucket-presents-beers-with-bitbucket#/ Microsoft is sponsoring a dinner that evening at 8pm for just contributor summit attendees. Details will be provided at the summit. I look forward to seeing everybody there! -Peff
Re: Worktree silently deleted on git fetch/gc/log
On Fri, Mar 2, 2018 at 6:53 AM, Duy Nguyenwrote: > I'm going to improve it a bit in this case either way, I think I have > some idea: (mostly to Eric) since worktree B is alive and kicking, it > should keep at least HEAD or index updated often. We can delay > deleting a worktree until both of these are past expire time. Make sense. > Also Eric (and this is getting off topic), I wonder if the decision to > store absolute path in worktrees/../gitdir and .git files is a bad one > (and is my bad). Your original implementation of worktrees was able to recover automatically when a worktree was moved (via 'mv', for instance). That feature pretty much required recording an absolute path in the worktree's .git file. When the automatic-recovery feature was dropped, I suppose the need for absolute path in the .git file disappeared, as well. I can't presently think of a reason why gitdir needed/used an absolute or normalized path. Was it because there was some need to compare such paths? > If we stored relative path in ".git" file at least, the worktree would > immediately fail after the user moves either the linked checkout, or > the main one. This should send a loud and clear signal to the user > "something has gone horribly" and hopefully make them connect it to > the last rename and undo that. "git gc" would have near zero chance to > kick in and destroy stale worktrees. It would detect if the main or linked worktree moved up or down one or more directory levels or elsewhere. It would not detect if the worktree directory was merely renamed. Still, detecting some cases of breakage early may be better than not detecting breakage at all. Another idea may be to store the worktree's own normalized/absolute path as a second line in its .git file. It could then immediately detect any manual movement or renaming of itself. A minor concern, though, is if there are any external tools reading that file directly since they could be confused by the second line. Of course, such tools hopefully would be using "git rev-parse --git-dir", so maybe it wouldn't be a big deal. On the other hand, older versions of Git itself would be confused by the second line, so perhaps the idea isn't viable. > Another bad thing about absolute paths, if you backup both main and > linked worktrees in a tar file, restoring from the backup won't work > unless you restore at the exact same place. > Hmm? Yep, that's an issue. An even simpler case is the somewhat common usage pattern of creating worktrees within the main worktree (Dscho has a number of times mentioned working like this, and I've done it myself). In such a case, even just moving or renaming the main worktree breaks the linked ones when absolute paths are in play. So, yes, these issue argue for use of relative paths.
Re: [PATCH] smart-http: document flush after "# service" line
On Sat, Mar 03, 2018 at 03:28:47AM -0500, Eric Sunshine wrote: > On Sat, Mar 3, 2018 at 12:27 AM, Jeff Kingwrote: > > Subject: smart-http: document flush after "# service" line > > > > The http-protocol.txt spec fails to mention that a flush > > packet comes in the smart server response after sending any > > the "service" header. > > "any the"? Oops, should just be "the". -Peff
git stash push -u always warns "pathspec '...' did not match any files"
Reproducible in a test repository with following steps: $ touch untracked $ git stash push -u -- untracked Saved working directory and index state WIP on master: 0096475 init fatal: pathspec 'untracked' did not match any files error: unrecognized input The file is stashed correctly, though. Tested with Git 2.16.2 on Linux and Windows. -Marc
Re: [PATCH 1/2] completion: don't set PARSE_OPT_NOCOMPLETE on --rerere-autoupdate
On Sat, Mar 3, 2018 at 4:23 AM, Nguyễn Thái Ngọc Duywrote: > There is not a strong reason to hide this option, and git-merge already > completes this one. Let's allow to complete this for all commands (and > let git-completion.bash do the suppressing if neede). s/neede/needed/ > This makes --rerere-autoupdate completable for am, cherry-pick and > revert. > > Signed-off-by: Nguyễn Thái Ngọc Duy
Re: [PATCH 3/3] worktree prune: improve prune logic when worktree is moved
On Fri, Mar 2, 2018 at 10:39 PM, Nguyễn Thái Ngọc Duywrote: > Worktree manual move support is actually gone in 618244e160 (worktree: > stop supporting moving worktrees manually - 2016-01-22). Before that, > this gitdir could be updated often when the worktree is accessed. That > keeps the worktree from being pruned by this logic. I had a bit of trouble digesting this paragraph. Possible rewrite: Automatic detection of worktree relocation by a user (via 'mv', for instance) was removed by 618244e160 (worktree: stop supporting moving worktrees manually - 2016-01-22). Prior to that, .git/worktrees//gitdir was updated whenever the worktree was accessed in order to let the pruning logic know that the worktree was "active" even if it disappeared for a while (due to being located on removable media, for instance). > "git worktree move" is coming so we don't really need this, but since > it's easy to do, perhaps we could keep supporting manual worktree move a > bit longer. Notice that when a worktree is active, the "index" file > should be updated pretty often in common case. The logic is updated to > check for index mtime to see if the worktree is alive. Seems like a reasonable approximation of the pre-618244e160 way things worked. > Signed-off-by: Nguyễn Thái Ngọc Duy > --- > diff --git a/builtin/worktree.c b/builtin/worktree.c > @@ -101,6 +101,9 @@ static int prune_worktree(const char *id, struct strbuf > *reason) > if (!file_exists(path)) { > free(path); > if (st.st_mtime <= expire) { This st.st_mtime is that of 'gitdir'... > + if (!stat(git_path("worktrees/%s/index", id), ) && > + st.st_mtime > expire) ...and this st.st_mtime is of 'index'. I wonder if it the 'gitdir' mtime check is really that useful anymore considering that 'index' mtime will almost certainly be more recent. > + return 0; > strbuf_addf(reason, _("Removing worktrees/%s: gitdir > file points to non-existent location"), id); > return 1;
[PATCH 0/2] nd/parseopt-completion fixups
This addresses some comments from v3 [1]. Since the series has been merged to 'next', we do incremental updates instead: - --rerere-autoupdate is completable on am, revert and cherry-pick - simplification in _git_notes which leads to completion in 'git notes remove' [1] https://public-inbox.org/git/20180209110221.27224-1-pclo...@gmail.com/ Nguyễn Thái Ngọc Duy (2): completion: don't set PARSE_OPT_NOCOMPLETE on --rerere-autoupdate completion: simplify _git_notes contrib/completion/git-completion.bash | 18 +++--- parse-options.h| 4 ++-- rerere.h | 3 +-- 3 files changed, 6 insertions(+), 19 deletions(-) -- 2.16.1.435.g8f24da2e1a
[PATCH 2/2] completion: simplify _git_notes
This also adds completion for 'git notes remove' with two options: --ignore-missing and --stdin. For some strange reason, 'git notes undefined --' completes --ref without even running --git-completion-helper. But since this is an error case (and we're not doing anything destructive, it's probably ok for now) Signed-off-by: Nguyễn Thái Ngọc Duy--- contrib/completion/git-completion.bash | 15 ++- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index c310b241d3..ab80f4e6e8 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1836,19 +1836,8 @@ _git_notes () add,--reedit-message=*|append,--reedit-message=*) __git_complete_refs --cur="${cur#*=}" ;; - add,--*) - __gitcomp_builtin notes_add - ;; - append,--*) - __gitcomp_builtin notes_append - ;; - copy,--*) - __gitcomp_builtin notes_copy - ;; - prune,--*) - __gitcomp_builtin notes_prune - ;; - prune,*) + *,--*) + __gitcomp_builtin notes_$subcommand ;; *) case "$prev" in -- 2.16.1.435.g8f24da2e1a
[PATCH 1/2] completion: don't set PARSE_OPT_NOCOMPLETE on --rerere-autoupdate
There is not a strong reason to hide this option, and git-merge already completes this one. Let's allow to complete this for all commands (and let git-completion.bash do the suppressing if neede). This makes --rerere-autoupdate completable for am, cherry-pick and revert. Signed-off-by: Nguyễn Thái Ngọc Duy--- contrib/completion/git-completion.bash | 3 +-- parse-options.h| 4 ++-- rerere.h | 3 +-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 0ddf40063b..c310b241d3 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1754,8 +1754,7 @@ _git_merge () case "$cur" in --*) - __gitcomp_builtin merge "--rerere-autoupdate - --no-rerere-autoupdate + __gitcomp_builtin merge "--no-rerere-autoupdate --no-commit --no-edit --no-ff --no-log --no-progress --no-squash --no-stat diff --git a/parse-options.h b/parse-options.h index 0ba08691e6..ab1cc362bf 100644 --- a/parse-options.h +++ b/parse-options.h @@ -148,8 +148,8 @@ struct option { #define OPT_STRING_LIST(s, l, v, a, h) \ { OPTION_CALLBACK, (s), (l), (v), (a), \ (h), 0, _opt_string_list } -#define OPT_UYN(s, l, v, h, f) { OPTION_CALLBACK, (s), (l), (v), NULL, \ - (h), PARSE_OPT_NOARG|(f), _opt_tertiary } +#define OPT_UYN(s, l, v, h) { OPTION_CALLBACK, (s), (l), (v), NULL, \ + (h), PARSE_OPT_NOARG, _opt_tertiary } #define OPT_DATE(s, l, v, h) \ { OPTION_CALLBACK, (s), (l), (v), N_("time"),(h), 0,\ parse_opt_approxidate_cb } diff --git a/rerere.h b/rerere.h index 5e5a312e4c..c2961feaaa 100644 --- a/rerere.h +++ b/rerere.h @@ -37,7 +37,6 @@ extern void rerere_clear(struct string_list *); extern void rerere_gc(struct string_list *); #define OPT_RERERE_AUTOUPDATE(v) OPT_UYN(0, "rerere-autoupdate", (v), \ - N_("update the index with reused conflict resolution if possible"), \ - PARSE_OPT_NOCOMPLETE) + N_("update the index with reused conflict resolution if possible")) #endif -- 2.16.1.435.g8f24da2e1a
Re: [PATCH 1/3] gc.txt: more details about what gc does
On Fri, Mar 2, 2018 at 10:39 PM, Nguyễn Thái Ngọc Duywrote: > Signed-off-by: Nguyễn Thái Ngọc Duy > --- > diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.txt > @@ -15,8 +15,9 @@ DESCRIPTION > --- > Runs a number of housekeeping tasks within the current repository, > such as compressing file revisions (to reduce disk space and increase > -performance) and removing unreachable objects which may have been > -created from prior invocations of 'git add'. > +performance), removing unreachable objects which may have been > +created from prior invocations of 'git add', packing refs, pruning > +reflog, rerere or stale working trees. s/rerere/& metadata/ > Users are encouraged to run this task on a regular basis within > each repository to maintain good disk space utilization and good > @@ -59,6 +60,10 @@ then existing packs (except those marked with a `.keep` > file) > are consolidated into a single pack by using the `-A` option of > 'git repack'. Setting `gc.autoPackLimit` to 0 disables > automatic consolidation of packs. > ++ > +If `git gc --auto` goes ahead because of either too loose objects or > +packs, all other housekeeping tasks (e.g. rerere, working trees, > +reflog...) will also be be performed. s/be be/be/ Perhaps this new paragraph should be moved up by one paragraph; the result feels a bit more cohesive. Minor rewrite: If `git gc --auto` finds that housekeeping is required due to too many loose objects or packs, all other housekeeping tasks (e.g. rerere, working trees, reflog...) will be performed, as well. > @@ -133,6 +138,9 @@ The optional configuration variable `gc.pruneExpire` > controls how old > the unreferenced loose objects have to be before they are pruned. The > default is "2 weeks ago". > > +The optional gc.worktreePruneExpire controls how old a stale working > +tree before `git worktree prune` deletes it. The default is "3 months > +ago". > > Notes > - Missing backticks around "gc.worktreePruneExpire". s/tree before/tree should be before/ You lost a blank line before the "Notes" section. With minor fixes: Optional configuration variable `gc.worktreePruneExpire` controls how old a stale working tree should be before `git worktree prune` deletes it. Default is "3 months ago".
Re: [PATCH] git.el: handle default excludesfile properly
On Fri, Mar 2, 2018 at 10:48 PM, Dorab Patelwrote: > The previous version only looked at core.excludesfile for locating the > excludesfile. So, when core.excludesfile was not defined, it did not > use the possible default locations. > > The current version uses either $XDG_CONFIG_HOME/git/ignore or > $HOME/.config/git/ignore for the default excludesfile location > depending on whether XDG_CONFIG_HOME is defined or not. As per the > documentation of gitignore. Perhaps take $HOME/.gitignore into account too? > Signed-off-by: Dorab Patel
Re: [PATCH] smart-http: document flush after "# service" line
On Sat, Mar 3, 2018 at 12:27 AM, Jeff Kingwrote: > Subject: smart-http: document flush after "# service" line > > The http-protocol.txt spec fails to mention that a flush > packet comes in the smart server response after sending any > the "service" header. "any the"? > Technically the client code is actually ready to receive an > arbitrary number of headers here, but since we haven't > introduced any other headers in the past decade (and the > client would just throw them away), let's not mention it in > the spec. > > This fixes both BNF and the example. While we're fixing the > latter, let's also add the missing flush after the ref list. > > Reported-by: Dorian Taylor > Signed-off-by: Jeff King