* Re: [PATCH] fetch: print an error when declining to request an unadvertised object
From: Junio C Hamano @ 2017-02-12 23:49 UTC (permalink / raw)
To: Matt McCutchen; +Cc: git
In-Reply-To: <1486934007.8517.10.camel@mattmccutchen.net>
Matt McCutchen <matt@mattmccutchen.net> writes:
> What do you think? Do you not care about having a more specific error,
> in which case I can copy the code from builtin/fetch-pack.c to
> fetch_refs_via_pack? Or shall I add code to filter_refs to set a flag
> and add code to builtin/fetch-pack.c and fetch_refs_via_pack to check
> the flag? Or what?
The fact that we have the above two choices tells me that a two-step
approach may be an appropriate approach.
The first step is to teach fetch_refs_via_pack() that it should not
ignore the information returned in sought[]. It would add new code
similar to what cmd_fetch_pack() uses to notice and report errors
[*1*] to the function. It would be a sensible first step, but would
not let the user know which of multiple causes of "not matched" we
noticed.
By "a more specific error", I think you are envisioning that the
current boolean "matched" is made into an enum that allows the
caller to tell how each request did not match [*2*]. That can be
the topic of the second patch and would have to touch filter_refs()
[*3*], cmd_fetch_pack() and fetch_refs_via_pack().
I do not have strong preference myself offhand between stopping at
the first step or completing both.
Even if you did only the first step, as long as the second step can
be done without reverting what the first step did [*4*] by somebody
who cares the "specific error" deeply enough, I am OK with that. Of
course if you did both steps, that is fine by me as well ;-)
[Footnote]
*1* While I know that it is not right to die() in filter_refs(), and
fetch_refs_via_pack() is a better place to notice errors, I do
not offhand know if it is the right place to report errors, or a
caller higher in the callchain may want the callee to be silent
and wants to show its own error message (in which case the error
may have to percolate upwards in the callchain).
*2* e.g. "was it a ref but they did not advertise? Did it request
an explicit object name and they did not allow it?" We may want
to support other "more specific" errors that can be detected in
the future.
*3* The current code flips the sought[i]->matched bit on for matched
ones (relying on the initial state of the bit being false), but
it now needs to stuff different kind of "not matched" to the
field to allow the caller to act on it.
*4* IOW, I am OK with an initial "small" improvement, but I'd want
to make sure that such an initial step does not make future
enhancements by others harder.
^ permalink raw reply
* [PATCH] completion: teach to complete git-subtree
From: cornelius.weig @ 2017-02-13 1:07 UTC (permalink / raw)
To: git
Cc: bitte.keine.werbung.einwerfen, Cornelius Weig, szeder.dev, s6t,
greened, davvid
From: Cornelius Weig <cornelius.weig@tngtech.com>
Git-subtree is a contrib-command without completion, making it
cumbersome to use.
Teach bash completion to complete the subcommands of subtree (add,
merge, pull, push, split) and options thereof. For subcommands
supporting it (add, push, pull) also complete remote names and refspec.
Signed-off-by: Cornelius Weig <cornelius.weig@tngtech.com>
---
contrib/completion/git-completion.bash | 35 ++++++++++++++++++++++++++++++----
1 file changed, 31 insertions(+), 4 deletions(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 6c6e1c7..430bfed 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -535,9 +535,9 @@ __git_complete_remote_or_refspec ()
{
local cur_="$cur" cmd="${words[1]}"
local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0
- if [ "$cmd" = "remote" ]; then
- ((c++))
- fi
+ case "$cmd" in
+ remote|subtree) ((c++)) ;;
+ esac
while [ $c -lt $cword ]; do
i="${words[c]}"
case "$i" in
@@ -586,7 +586,7 @@ __git_complete_remote_or_refspec ()
__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
fi
;;
- pull|remote)
+ pull|remote|subtree)
if [ $lhs = 1 ]; then
__gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
else
@@ -2569,6 +2569,33 @@ _git_submodule ()
fi
}
+_git_subtree ()
+{
+ local subcommands="add merge pull push split"
+ local subcommand="$(__git_find_on_cmdline "$subcommands")"
+ if [ -z "$subcommand" ]; then
+ __gitcomp "$subcommands"
+ return
+ fi
+ case "$subcommand,$cur" in
+ add,--*|merge,--*|pull,--*)
+ __gitcomp "--prefix= --squash --message="
+ ;;
+ push,--*)
+ __gitcomp "--prefix="
+ ;;
+ split,--*)
+ __gitcomp "
+ --annotate= --branch= --ignore-joins
+ --onto= --prefix= --rejoin
+ "
+ ;;
+ add,*|push,*|pull,*)
+ __git_complete_remote_or_refspec
+ ;;
+ esac
+}
+
_git_svn ()
{
local subcommands="
--
2.10.2
^ permalink raw reply related
* Re: [PATCH 0/5] Store submodules in a hash, not a linked list
From: Duy Nguyen @ 2017-02-13 2:39 UTC (permalink / raw)
To: Jeff King
Cc: Michael Haggerty, Junio C Hamano, Stefan Beller,
Johannes Schindelin, David Turner, git
In-Reply-To: <20170210004033.cgqmovhvoylad5cf@sigill.intra.peff.net>
On Thu, Feb 09, 2017 at 07:40:33PM -0500, Jeff King wrote:
> On Thu, Feb 09, 2017 at 10:23:35PM +0100, Michael Haggerty wrote:
>
> > >> So push the submodule attribute down to the `files_ref_store` class
> > >> (but continue to let the `ref_store`s be looked up by submodule).
> > >
> > > I'm not sure I understand all of the ramifications here. It _sounds_ like
> > > pushing this down into the files-backend code would make it harder to
> > > have mixed ref-backends for different submodules. Or is this just
> > > pushing down an implementation detail of the files backend, and future
> > > code is free to have as many different ref_stores as it likes?
> >
> > I don't understand how this would make it harder, aside from the fact
> > that a new backend class might also need a path member and have to
> > maintain its own copy rather than using one that the base class provides.
>
> Probably the answer is "I'm really confused".
>
> But here's how my line of reasoning went:
>
> Right now we have a main ref-store that points to the submodule
> ref-stores. I don't know the current state of it, but in theory those
> could all use different backends.
>
> This seems like it's pushing that submodule linkage down into the
> backend.
>
> But I think from your response that the answer is no, the thing that is
> being pushed down is not the right way for the main ref store and the
> submodules to be linked.
I think it's more about "pushing out" than "pushing down". Once files
backend takes a path to .git directory, we could have a submodule
ref_store that resolves submodule path to that .git directory,
files-backend will not need to know anything about submodules.
I imagine in future lookup_ref_store() will take a .git path instead
of a submodule path, then iterate through all backends and call the
backend-specific "probe" function to let the backend figure out if
it's the right backend and whatever parameters it needs (e.g. IP
address or path). There would be submodule_lookup_ref_store() wrapper
that converts submodule path to .git path for lookup_ref_store() to
consume.
--
Duy
^ permalink raw reply
* Incorrect pipe for git log graph when using --name-status option
From: hIpPy @ 2017-02-13 2:49 UTC (permalink / raw)
To: git
The `git log` command with `graph` and pretty format works correctly
as expected.
$ git log --graph --pretty=format:'%h' -2
* 714a14e
* 87dce5f
However, with `--name-status` option added, there is a pipe
incorrectly placed after the commit hash (example below).
$ git log --graph --pretty=format:'%h' -2 --name-status
* 714a14e|
| M README.md
| A rm.Extensions/BitSet.cs
| M rm.Extensions/Properties/AssemblyInfo.cs
| M rm.Extensions/rm.Extensions.csproj
| A rm.ExtensionsTest/BitSetTest.cs
| M rm.ExtensionsTest/rm.ExtensionsTest.csproj
* 87dce5f|
| M rm.Extensions/GraphExtension.cs
| M rm.Extensions/Wrapped.cs
| M rm.Extensions/WrappedExtension.cs
| M rm.Extensions/rm.Extensions.csproj
IMHO, I think this is a bug. I think the correct output should be
below.
$ git log --graph --pretty=format:'%h' -2 --name-status
* 714a14e
| M README.md
| A rm.Extensions/BitSet.cs
| M rm.Extensions/Properties/AssemblyInfo.cs
| M rm.Extensions/rm.Extensions.csproj
| A rm.ExtensionsTest/BitSetTest.cs
| M rm.ExtensionsTest/rm.ExtensionsTest.csproj
|
* 87dce5f
| M rm.Extensions/GraphExtension.cs
| M rm.Extensions/Wrapped.cs
| M rm.Extensions/WrappedExtension.cs
| M rm.Extensions/rm.Extensions.csproj
I'm using this:
git version 2.11.0.windows.1
GNU bash, version 4.3.46(2)-release (x86_64-pc-msys)
Windows 8.1 64-bit
Thanks,
RM
^ permalink raw reply
* Re: [PATCH v2 0/9] Store submodules in a hash, not a linked list
From: David Turner @ 2017-02-13 3:09 UTC (permalink / raw)
To: Michael Haggerty, Junio C Hamano
Cc: Nguyễn Thái Ngọc Duy, Stefan Beller,
Johannes Schindelin, Jeff King, git
In-Reply-To: <cover.1486724698.git.mhagger@alum.mit.edu>
On Fri, 2017-02-10 at 12:16 +0100, Michael Haggerty wrote:
> This is v2 of the patch series, considerably reorganized but not that
> different codewise. Thanks to Stefan, Junio, and Peff for their
> feedback about v1 [1]. I think I have addressed all of your comments.
LGTM.
^ permalink raw reply
* Re: Working with public-inbox.org [Was: [PATCH] rev-parse: respect core.hooksPath in --git-path]
From: Arif Khokar @ 2017-02-13 5:52 UTC (permalink / raw)
To: Johannes Schindelin, Arif Khokar
Cc: Jakub Narębski, Jeff King, Stefan Beller,
meta@public-inbox.org, git@vger.kernel.org, Eric Wong
In-Reply-To: <alpine.DEB.2.20.1702101707060.3496@virtualbox>
On 02/10/2017 11:10 AM, Johannes Schindelin wrote:
> Hi Arif,
>
> On Wed, 24 Aug 2016, Johannes Schindelin wrote:
>> I recently adapted an old script I had to apply an entire patch series
>> given the GMane link to its cover letter:
>>
>> https://github.com/git-for-windows/build-extra/blob/master/apply-from-gmane.sh
>>
>> Maybe you find it in you to adapt that to work with public-inbox.org?
>
> Oh well. That would have been too easy a task, right?
>
> As it happens, I needed this functionality myself (when reworking my
> git-path-in-subdir patch to include Mike Rappazzo's previous patch series
> that tried to fix the same bug).
>
> I copy-edited the script to work with public-inbox.org, it accepts a
> Message-ID or URL or GMane URL and will try to apply the patch (or patch
> series) on top of the current revision:
>
> https://github.com/git-for-windows/build-extra/blob/2268850552c7/apply-from-public-inbox.sh
Thanks for the link. One thing that comes to mind that is that it may
be better to just download the patches and then manually apply them
afterwords rather than doing it in the script itself. Or at least add
an option to the script to not automatically invoke git am.
Getting back to the point I made when this thread was still active, I
still think it would be better to be able to list the message-id values
in the header or body of the cover letter message of a patch series
(preferably the former) in order to facilitate downloading the patches
via NNTP from gmane or public-inbox.org. That would make it easier
compared to the different, ad-hoc, methods that exist for each email client.
Alternatively, or perhaps in addition to the list of message-ids, a list
of URLs to public-inbox.org or gmane messages could also be provided for
those who prefer to download patches via HTTP.
^ permalink raw reply
* Re: Git status performance on PS (command prompt)
From: Christian Couder @ 2017-02-13 6:12 UTC (permalink / raw)
To: brian m. carlson, Mark Gaiser, git
In-Reply-To: <20170212164650.u7frv234kmu5hm7r@genre.crustytoothpaste.net>
On Sun, Feb 12, 2017 at 5:46 PM, brian m. carlson
<sandals@crustytoothpaste.net> wrote:
> On Sun, Feb 12, 2017 at 04:53:47PM +0100, Mark Gaiser wrote:
[...]
>> I did a bit of profiling in git to figure out where this slowdown comes from.
>> Callgrind tells me that "read_directory_recursive" takes up ~62% of the time.
>> Within that call the function "last_exclude_matching_from_list" takes
>> up 49% of the time it takes to run "git status --porcelain -b".
The core.untrackedCache config option may help.
^ permalink raw reply
* Re: [PATCH v2 9/9] read_loose_refs(): read refs using resolve_ref_recursively()
From: Michael Haggerty @ 2017-02-13 6:40 UTC (permalink / raw)
To: Junio C Hamano
Cc: Nguyễn Thái Ngọc Duy, Stefan Beller,
Johannes Schindelin, David Turner, Jeff King, git
In-Reply-To: <xmqqbmu9lul6.fsf@gitster.mtv.corp.google.com>
On 02/10/2017 08:22 PM, Junio C Hamano wrote:
> Michael Haggerty <mhagger@alum.mit.edu> writes:
>> [...]
>
> OK, but one thing puzzles me...
>
>> @@ -1390,27 +1390,6 @@ static struct ref_store *main_ref_store;
>> static struct hashmap submodule_ref_stores;
>>
>> /*
>> - * Return the ref_store instance for the specified submodule (or the
>> - * main repository if submodule is NULL). If that ref_store hasn't
>> - * been initialized yet, return NULL.
>> - */
>> -static struct ref_store *lookup_ref_store(const char *submodule)
>> -{
>> - struct submodule_hash_entry *entry;
>> -
>> - if (!submodule)
>> - return main_ref_store;
>> -
>> - if (!submodule_ref_stores.tablesize)
>> - /* It's initialized on demand in register_ref_store(). */
>> - return NULL;
>> -
>> - entry = hashmap_get_from_hash(&submodule_ref_stores,
>> - strhash(submodule), submodule);
>> - return entry ? entry->refs : NULL;
>> -}
>> -
>> -/*
>> * Register the specified ref_store to be the one that should be used
>> * for submodule (or the main repository if submodule is NULL). It is
>> * a fatal error to call this function twice for the same submodule.
>> @@ -1451,6 +1430,27 @@ static struct ref_store *ref_store_init(const char *submodule)
>> return refs;
>> }
>>
>> +/*
>> + * Return the ref_store instance for the specified submodule (or the
>> + * main repository if submodule is NULL). If that ref_store hasn't
>> + * been initialized yet, return NULL.
>> + */
>> +static struct ref_store *lookup_ref_store(const char *submodule)
>> +{
>> + struct submodule_hash_entry *entry;
>> +
>> + if (!submodule)
>> + return main_ref_store;
>> +
>> + if (!submodule_ref_stores.tablesize)
>> + /* It's initialized on demand in register_ref_store(). */
>> + return NULL;
>> +
>> + entry = hashmap_get_from_hash(&submodule_ref_stores,
>> + strhash(submodule), submodule);
>> + return entry ? entry->refs : NULL;
>> +}
>> +
>
> I somehow thought that we had an early "reorder the code" step to
> avoid hunks like these? Am I missing some subtle changes made while
> moving the function down?
You are quite right; thanks for noticing. I forgot to un-move this
function when re-rolling. These two hunks can be discarded (the function
text is unchanged).
I pushed the fixed commit to branch `submodule-hash` in my fork [1]. If
you'd like me to send it to the mailing list again, please let me know.
Michael
[1] https://github.com/mhagger/git
^ permalink raw reply
* Re: [RFC PATCH] show decorations at the end of the line
From: Junio C Hamano @ 2017-02-13 8:30 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <CA+55aFw2S14a4_4YK0b6PNK4TH_AUo_+2JN+PTyBTufNeB5t6A@mail.gmail.com>
Linus Torvalds <torvalds@linux-foundation.org> writes:
> On Sat, Feb 11, 2017 at 10:02 AM, Linus Torvalds
> <torvalds@linux-foundation.org> wrote:
>>
>> I've signed off on this, because I think it's an "obvious" improvement,
>> but I'm putting the "RFC" in the subject line because this is clearly a
>> subjective thing.
>
> Side note: the one downside of showing the decorations at the end of
> the line is that now they are obviously at the end of the line - and
> thus likely to be more hidden by things like line truncation.
Side note: I refrained from commenting on this patch because
everybody knows that the what I would say anyway ;-) and I didn't
want to speak first to discourage others from raising their opinion.
An obvious downside is that people (against all recommendations) are
likely to have written a loose script expecting the --oneline format
is cast in stone. I personally think it is OK to break them as long
as "workaround" (aka kosher way to do what they have been doing) is
obvious and easily doable, and in this case their script can switch
to use --format to keep using the order of fields and format they
have been relying on.
It would be nice if we can have that --format string they can use
somewhere in the log message, so that I can cut & paste it into the
release notes that contains this change (i.e. "those who want to
keep using the traditional --oneline --decorate can use this string
as pretty.my1line configuration variable and use --pretty=my1line
instead").
^ permalink raw reply
* [PATCH] clean: use warning_errno() when appropriate
From: Nguyễn Thái Ngọc Duy @ 2017-02-13 9:27 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
All these warning() calls are preceded by a system call. Report the
actual error to help the user understand why we fail to remove
something.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/clean.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/builtin/clean.c b/builtin/clean.c
index d6bc3aaaea..dc1168747e 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -175,7 +175,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
res = dry_run ? 0 : rmdir(path->buf);
if (res) {
quote_path_relative(path->buf, prefix, "ed);
- warning(_(msg_warn_remove_failed), quoted.buf);
+ warning_errno(_(msg_warn_remove_failed), quoted.buf);
*dir_gone = 0;
}
return res;
@@ -209,7 +209,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
string_list_append(&dels, quoted.buf);
} else {
quote_path_relative(path->buf, prefix, "ed);
- warning(_(msg_warn_remove_failed), quoted.buf);
+ warning_errno(_(msg_warn_remove_failed), quoted.buf);
*dir_gone = 0;
ret = 1;
}
@@ -231,7 +231,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
*dir_gone = 1;
else {
quote_path_relative(path->buf, prefix, "ed);
- warning(_(msg_warn_remove_failed), quoted.buf);
+ warning_errno(_(msg_warn_remove_failed), quoted.buf);
*dir_gone = 0;
ret = 1;
}
@@ -982,7 +982,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
res = dry_run ? 0 : unlink(abs_path.buf);
if (res) {
qname = quote_path_relative(item->string, NULL, &buf);
- warning(_(msg_warn_remove_failed), qname);
+ warning_errno(_(msg_warn_remove_failed), qname);
errors++;
} else if (!quiet) {
qname = quote_path_relative(item->string, NULL, &buf);
--
2.11.0.157.gd943d85
^ permalink raw reply related
* Re: Working with public-inbox.org [Was: [PATCH] rev-parse: respect core.hooksPath in --git-path]
From: Johannes Schindelin @ 2017-02-13 14:37 UTC (permalink / raw)
To: Arif Khokar
Cc: Arif Khokar, Jakub Narębski, Jeff King, Stefan Beller,
meta@public-inbox.org, git@vger.kernel.org, Eric Wong
In-Reply-To: <d16546a4-25be-7b85-3191-e9393fda1164@hotmail.com>
Hi Arif,
On Mon, 13 Feb 2017, Arif Khokar wrote:
> On 02/10/2017 11:10 AM, Johannes Schindelin wrote:
> >
> > On Wed, 24 Aug 2016, Johannes Schindelin wrote:
>
> > > I recently adapted an old script I had to apply an entire patch
> > > series given the GMane link to its cover letter:
> > >
> > > https://github.com/git-for-windows/build-extra/blob/master/apply-from-gmane.sh
> > >
> > > Maybe you find it in you to adapt that to work with
> > > public-inbox.org?
> >
> > Oh well. That would have been too easy a task, right?
> >
> > As it happens, I needed this functionality myself (when reworking my
> > git-path-in-subdir patch to include Mike Rappazzo's previous patch
> > series that tried to fix the same bug).
> >
> > I copy-edited the script to work with public-inbox.org, it accepts a
> > Message-ID or URL or GMane URL and will try to apply the patch (or
> > patch series) on top of the current revision:
> >
> > https://github.com/git-for-windows/build-extra/blob/2268850552c7/apply-from-public-inbox.sh
>
> Thanks for the link. One thing that comes to mind that is that it may
> be better to just download the patches and then manually apply them
> afterwords rather than doing it in the script itself. Or at least add
> an option to the script to not automatically invoke git am.
I actually had expected *you* to put in a little bit of an effort, too. In
fact, I was very disappointed that you did not even look into porting that
script to use public-inbox instead of GMane.
> Getting back to the point I made when this thread was still active, I
> still think it would be better to be able to list the message-id values
> in the header or body of the cover letter message of a patch series
> (preferably the former) in order to facilitate downloading the patches
> via NNTP from gmane or public-inbox.org. That would make it easier
> compared to the different, ad-hoc, methods that exist for each email
> client.
You can always do that yourself: you can modify your cover letter to
include that information.
Note that doing this automatically in format-patch may not be appropriate,
as 1) the Message-ID could be modified depending on the mail client used
to send the mails, and 2) it is not unheard of that a developer
finds a bug in the middle of sending a patch series, fixes that bug, and
regenerates the remainder of the patch series, completely rewriting those
Message-IDs.
> Alternatively, or perhaps in addition to the list of message-ids, a list
> of URLs to public-inbox.org or gmane messages could also be provided for
> those who prefer to download patches via HTTP.
At this point, I am a little disinterested in a discussion without code. I
brought some code to the table, after all.
Ciao,
Johannes
^ permalink raw reply
* [PATCH/RFC 00/11] Remove submodule from files-backend.c
From: Nguyễn Thái Ngọc Duy @ 2017-02-13 15:20 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Michael Haggerty, Johannes Schindelin, sbeller,
novalis, Nguyễn Thái Ngọc Duy
This is on top of mh/submodule-hash, it:
- centralizes path manipulation around submodule, $GIT_DIR... in
files-backend.c to a new function files_path() with the intention
to make it easier to change later. files_path() is destined to
become
strbuf_addbuf(&sb, refs->gitdir);
strbuf_complete(&sb, '/');
strbuf_vaddf(&sb, fmt, vap);
but that can only be achieved once we get compound ref store.
- removes git_path() and submodule_git_path() from files-backend.c. No
more magic path translation as far as ref backend is concerned.
- moves submodule path resolution code outside the backend.
files-backend is now oblivious of submodules and in theory a
submodule ref-store supports all operations (but I could be wrong,
I didn't stare hard)
- exposes get_submodule_ref_store() and get_main_ref_store() as public
API. A new set of API around ref-store will be added. And
get_worktree_ref_store() of course. The *_submodule() API might be
removed, we'll see.
The problem with set_worktree_head_symref() (which peeks into another
gitdir) should be solved once we have get_worktree_ref_store(). That's
my next step.
Compound ref store will have to wait until I'm done with my
gc-in-worktree problem as I think I can live without it for now. I
think after compound ref store is in place, adding lmdb backend back
should be much cleaner because it does not care about either
submodules or worktrees.
Nguyễn Thái Ngọc Duy (11):
refs-internal.c: make files_log_ref_write() static
files-backend: convert git_path() to strbuf_git_path()
files-backend: add files_path()
files-backend: replace *git_path*() with files_path()
refs.c: share is_per_worktree_ref() to files-backend.c
refs-internal.h: correct is_per_worktree_ref()
files-backend: remove the use of git_path()
refs.c: factor submodule code out of get_ref_store()
refs: move submodule code out of files-backend.c
files-backend: remove submodule_allowed from files_downcast()
refs: split and make get_*_ref_store() public API
refs.c | 125 ++++++++++++------
refs.h | 13 ++
refs/files-backend.c | 350 ++++++++++++++++++++++++++++++---------------------
refs/refs-internal.h | 28 ++---
4 files changed, 316 insertions(+), 200 deletions(-)
--
2.11.0.157.gd943d85
^ permalink raw reply
* [PATCH 03/11] files-backend: add files_path()
From: Nguyễn Thái Ngọc Duy @ 2017-02-13 15:20 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Michael Haggerty, Johannes Schindelin, sbeller,
novalis, Nguyễn Thái Ngọc Duy
In-Reply-To: <20170213152011.12050-1-pclouds@gmail.com>
This will be the replacement for both git_path() and git_path_submodule()
in this file. The idea is backend takes a git path and use that,
oblivious of submodule, linked worktrees and such.
This is the middle step towards that. Eventually the "submodule" field
in 'struct files_ref_store' should be replace by "gitdir". And a
compound ref_store is created to combine two files backends together,
one represents the shared refs in $GIT_COMMON_DIR, one per-worktree. At
that point, files_path() becomes a wrapper of strbuf_vaddf().
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
refs/files-backend.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 6582c9b2d..39217a2ca 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -169,6 +169,9 @@ static int files_log_ref_write(const char *refname, const unsigned char *old_sha
const unsigned char *new_sha1, const char *msg,
int flags, struct strbuf *err);
+void files_path(struct files_ref_store *refs, struct strbuf *sb,
+ const char *fmt, ...) __attribute__((format (printf, 3, 4)));
+
static struct ref_dir *get_ref_dir(struct ref_entry *entry)
{
struct ref_dir *dir;
@@ -930,6 +933,23 @@ struct files_ref_store {
/* Lock used for the main packed-refs file: */
static struct lock_file packlock;
+void files_path(struct files_ref_store *refs, struct strbuf *sb,
+ const char *fmt, ...)
+{
+ struct strbuf tmp = STRBUF_INIT;
+ va_list vap;
+
+ va_start(vap, fmt);
+ strbuf_vaddf(&tmp, fmt, vap);
+ va_end(vap);
+ if (refs->submodule)
+ strbuf_git_path_submodule(sb, refs->submodule,
+ "%s", tmp.buf);
+ else
+ strbuf_git_path(sb, "%s", tmp.buf);
+ strbuf_release(&tmp);
+}
+
/*
* Increment the reference count of *packed_refs.
*/
--
2.11.0.157.gd943d85
^ permalink raw reply related
* [PATCH 02/11] files-backend: convert git_path() to strbuf_git_path()
From: Nguyễn Thái Ngọc Duy @ 2017-02-13 15:20 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Michael Haggerty, Johannes Schindelin, sbeller,
novalis, Nguyễn Thái Ngọc Duy
In-Reply-To: <20170213152011.12050-1-pclouds@gmail.com>
git_path() and friends are going to be killed in files-backend.c in near
future. And because there's a risk with overwriting buffer in
git_path(), let's convert them all to strbuf_git_path(). We'll have
easier time killing/converting strbuf_git_path() then because we won't
have to worry about memory management again.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
refs/files-backend.c | 114 ++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 90 insertions(+), 24 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 75565c3aa..6582c9b2d 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -2169,6 +2169,8 @@ static int lock_packed_refs(struct files_ref_store *refs, int flags)
static int timeout_configured = 0;
static int timeout_value = 1000;
struct packed_ref_cache *packed_ref_cache;
+ struct strbuf sb = STRBUF_INIT;
+ int ret;
files_assert_main_repository(refs, "lock_packed_refs");
@@ -2177,10 +2179,13 @@ static int lock_packed_refs(struct files_ref_store *refs, int flags)
timeout_configured = 1;
}
- if (hold_lock_file_for_update_timeout(
- &packlock, git_path("packed-refs"),
- flags, timeout_value) < 0)
+ strbuf_git_path(&sb, "packed-refs");
+ ret = hold_lock_file_for_update_timeout(&packlock, sb.buf,
+ flags, timeout_value);
+ strbuf_release(&sb);
+ if (ret < 0)
return -1;
+
/*
* Get the current packed-refs while holding the lock. If the
* packed-refs file has been modified since we last read it,
@@ -2335,6 +2340,9 @@ static void try_remove_empty_parents(char *name)
for (q = p; *q; q++)
;
while (1) {
+ struct strbuf sb = STRBUF_INIT;
+ int ret;
+
while (q > p && *q != '/')
q--;
while (q > p && *(q-1) == '/')
@@ -2342,7 +2350,10 @@ static void try_remove_empty_parents(char *name)
if (q == p)
break;
*q = '\0';
- if (rmdir(git_path("%s", name)))
+ strbuf_git_path(&sb, "%s", name);
+ ret = rmdir(sb.buf);
+ strbuf_release(&sb);
+ if (ret)
break;
}
}
@@ -2431,7 +2442,11 @@ static int repack_without_refs(struct files_ref_store *refs,
return 0; /* no refname exists in packed refs */
if (lock_packed_refs(refs, 0)) {
- unable_to_lock_message(git_path("packed-refs"), errno, err);
+ struct strbuf sb = STRBUF_INIT;
+
+ strbuf_git_path(&sb, "packed-refs");
+ unable_to_lock_message(sb.buf, errno, err);
+ strbuf_release(&sb);
return -1;
}
packed = get_packed_refs(refs);
@@ -2529,11 +2544,12 @@ static int rename_tmp_log(const char *newrefname)
{
int attempts_remaining = 4;
struct strbuf path = STRBUF_INIT;
+ struct strbuf tmp_renamed_log = STRBUF_INIT;
int ret = -1;
- retry:
- strbuf_reset(&path);
strbuf_git_path(&path, "logs/%s", newrefname);
+ strbuf_git_path(&tmp_renamed_log, TMP_RENAMED_LOG);
+ retry:
switch (safe_create_leading_directories_const(path.buf)) {
case SCLD_OK:
break; /* success */
@@ -2546,7 +2562,7 @@ static int rename_tmp_log(const char *newrefname)
goto out;
}
- if (rename(git_path(TMP_RENAMED_LOG), path.buf)) {
+ if (rename(tmp_renamed_log.buf, path.buf)) {
if ((errno==EISDIR || errno==ENOTDIR) && --attempts_remaining > 0) {
/*
* rename(a, b) when b is an existing
@@ -2574,6 +2590,7 @@ static int rename_tmp_log(const char *newrefname)
ret = 0;
out:
strbuf_release(&path);
+ strbuf_release(&tmp_renamed_log);
return ret;
}
@@ -2614,9 +2631,15 @@ static int files_rename_ref(struct ref_store *ref_store,
int flag = 0, logmoved = 0;
struct ref_lock *lock;
struct stat loginfo;
- int log = !lstat(git_path("logs/%s", oldrefname), &loginfo);
+ struct strbuf sb_oldref = STRBUF_INIT;
+ struct strbuf sb_newref = STRBUF_INIT;
+ struct strbuf tmp_renamed_log = STRBUF_INIT;
+ int log, ret;
struct strbuf err = STRBUF_INIT;
+ strbuf_git_path(&sb_oldref, "logs/%s", oldrefname);
+ log = !lstat(sb_oldref.buf, &loginfo);
+ strbuf_release(&sb_oldref);
if (log && S_ISLNK(loginfo.st_mode))
return error("reflog for %s is a symlink", oldrefname);
@@ -2630,7 +2653,12 @@ static int files_rename_ref(struct ref_store *ref_store,
if (!rename_ref_available(oldrefname, newrefname))
return 1;
- if (log && rename(git_path("logs/%s", oldrefname), git_path(TMP_RENAMED_LOG)))
+ strbuf_git_path(&sb_oldref, "logs/%s", oldrefname);
+ strbuf_git_path(&tmp_renamed_log, TMP_RENAMED_LOG);
+ ret = log && rename(sb_oldref.buf, tmp_renamed_log.buf);
+ strbuf_release(&sb_oldref);
+ strbuf_release(&tmp_renamed_log);
+ if (ret)
return error("unable to move logfile logs/%s to "TMP_RENAMED_LOG": %s",
oldrefname, strerror(errno));
@@ -2709,13 +2737,19 @@ static int files_rename_ref(struct ref_store *ref_store,
log_all_ref_updates = flag;
rollbacklog:
- if (logmoved && rename(git_path("logs/%s", newrefname), git_path("logs/%s", oldrefname)))
+ strbuf_git_path(&sb_newref, "logs/%s", newrefname);
+ strbuf_git_path(&sb_oldref, "logs/%s", oldrefname);
+ if (logmoved && rename(sb_newref.buf, sb_oldref.buf))
error("unable to restore logfile %s from %s: %s",
oldrefname, newrefname, strerror(errno));
+ strbuf_git_path(&tmp_renamed_log, TMP_RENAMED_LOG);
if (!logmoved && log &&
- rename(git_path(TMP_RENAMED_LOG), git_path("logs/%s", oldrefname)))
+ rename(tmp_renamed_log.buf, sb_oldref.buf))
error("unable to restore logfile %s from "TMP_RENAMED_LOG": %s",
oldrefname, strerror(errno));
+ strbuf_release(&sb_newref);
+ strbuf_release(&sb_oldref);
+ strbuf_release(&tmp_renamed_log);
return 1;
}
@@ -3111,22 +3145,32 @@ int set_worktree_head_symref(const char *gitdir, const char *target)
static int files_reflog_exists(struct ref_store *ref_store,
const char *refname)
{
+ struct strbuf sb = STRBUF_INIT;
struct stat st;
+ int ret;
/* Check validity (but we don't need the result): */
files_downcast(ref_store, 0, "reflog_exists");
- return !lstat(git_path("logs/%s", refname), &st) &&
- S_ISREG(st.st_mode);
+ strbuf_git_path(&sb, "logs/%s", refname);
+ ret = !lstat(sb.buf, &st) && S_ISREG(st.st_mode);
+ strbuf_release(&sb);
+ return ret;
}
static int files_delete_reflog(struct ref_store *ref_store,
const char *refname)
{
+ struct strbuf sb = STRBUF_INIT;
+ int ret;
+
/* Check validity (but we don't need the result): */
files_downcast(ref_store, 0, "delete_reflog");
- return remove_path(git_path("logs/%s", refname));
+ strbuf_git_path(&sb, "logs/%s", refname);
+ ret = remove_path(sb.buf);
+ strbuf_release(&sb);
+ return ret;
}
static int show_one_reflog_ent(struct strbuf *sb, each_reflog_ent_fn fn, void *cb_data)
@@ -3181,7 +3225,9 @@ static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store,
/* Check validity (but we don't need the result): */
files_downcast(ref_store, 0, "for_each_reflog_ent_reverse");
- logfp = fopen(git_path("logs/%s", refname), "r");
+ strbuf_git_path(&sb, "logs/%s", refname);
+ logfp = fopen(sb.buf, "r");
+ strbuf_release(&sb);
if (!logfp)
return -1;
@@ -3287,7 +3333,9 @@ static int files_for_each_reflog_ent(struct ref_store *ref_store,
/* Check validity (but we don't need the result): */
files_downcast(ref_store, 0, "for_each_reflog_ent");
- logfp = fopen(git_path("logs/%s", refname), "r");
+ strbuf_git_path(&sb, "logs/%s", refname);
+ logfp = fopen(sb.buf, "r");
+ strbuf_release(&sb);
if (!logfp)
return -1;
@@ -3369,12 +3417,15 @@ static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_st
{
struct files_reflog_iterator *iter = xcalloc(1, sizeof(*iter));
struct ref_iterator *ref_iterator = &iter->base;
+ struct strbuf sb = STRBUF_INIT;
/* Check validity (but we don't need the result): */
files_downcast(ref_store, 0, "reflog_iterator_begin");
base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable);
- iter->dir_iterator = dir_iterator_begin(git_path("logs"));
+ strbuf_git_path(&sb, "logs");
+ iter->dir_iterator = dir_iterator_begin(sb.buf);
+ strbuf_release(&sb);
return ref_iterator;
}
@@ -3843,8 +3894,13 @@ static int files_transaction_commit(struct ref_store *ref_store,
ret = TRANSACTION_GENERIC_ERROR;
goto cleanup;
}
- for_each_string_list_item(ref_to_delete, &refs_to_delete)
- unlink_or_warn(git_path("logs/%s", ref_to_delete->string));
+ for_each_string_list_item(ref_to_delete, &refs_to_delete) {
+ struct strbuf sb = STRBUF_INIT;
+
+ strbuf_git_path(&sb, "logs/%s", ref_to_delete->string);
+ unlink_or_warn(sb.buf);
+ strbuf_release(&sb);
+ }
clear_loose_ref_cache(refs);
cleanup:
@@ -4098,18 +4154,28 @@ static int files_reflog_expire(struct ref_store *ref_store,
static int files_init_db(struct ref_store *ref_store, struct strbuf *err)
{
+ struct strbuf sb = STRBUF_INIT;
+
/* Check validity (but we don't need the result): */
files_downcast(ref_store, 0, "init_db");
/*
* Create .git/refs/{heads,tags}
*/
- safe_create_dir(git_path("refs/heads"), 1);
- safe_create_dir(git_path("refs/tags"), 1);
+ strbuf_git_path(&sb, "refs/heads");
+ safe_create_dir(sb.buf, 1);
+ strbuf_reset(&sb);
+ strbuf_git_path(&sb, "refs/tags");
+ safe_create_dir(sb.buf, 1);
+ strbuf_reset(&sb);
if (get_shared_repository()) {
- adjust_shared_perm(git_path("refs/heads"));
- adjust_shared_perm(git_path("refs/tags"));
+ strbuf_git_path(&sb, "refs/heads");
+ adjust_shared_perm(sb.buf);
+ strbuf_reset(&sb);
+ strbuf_git_path(&sb, "refs/tags");
+ adjust_shared_perm(sb.buf);
}
+ strbuf_release(&sb);
return 0;
}
--
2.11.0.157.gd943d85
^ permalink raw reply related
* [PATCH 01/11] refs-internal.c: make files_log_ref_write() static
From: Nguyễn Thái Ngọc Duy @ 2017-02-13 15:20 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Michael Haggerty, Johannes Schindelin, sbeller,
novalis, Nguyễn Thái Ngọc Duy
In-Reply-To: <20170213152011.12050-1-pclouds@gmail.com>
Created in 5f3c3a4e6f (files_log_ref_write: new function - 2015-11-10)
but probably never used outside refs-internal.c
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
refs/files-backend.c | 3 +++
refs/refs-internal.h | 4 ----
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index cdb6b8ff5..75565c3aa 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -165,6 +165,9 @@ static struct ref_entry *create_dir_entry(struct files_ref_store *ref_store,
const char *dirname, size_t len,
int incomplete);
static void add_entry_to_dir(struct ref_dir *dir, struct ref_entry *entry);
+static int files_log_ref_write(const char *refname, const unsigned char *old_sha1,
+ const unsigned char *new_sha1, const char *msg,
+ int flags, struct strbuf *err);
static struct ref_dir *get_ref_dir(struct ref_entry *entry)
{
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 33adbf93b..59e65958a 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -222,10 +222,6 @@ struct ref_transaction {
enum ref_transaction_state state;
};
-int files_log_ref_write(const char *refname, const unsigned char *old_sha1,
- const unsigned char *new_sha1, const char *msg,
- int flags, struct strbuf *err);
-
/*
* Check for entries in extras that are within the specified
* directory, where dirname is a reference directory name including
--
2.11.0.157.gd943d85
^ permalink raw reply related
* [PATCH 04/11] files-backend: replace *git_path*() with files_path()
From: Nguyễn Thái Ngọc Duy @ 2017-02-13 15:20 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Michael Haggerty, Johannes Schindelin, sbeller,
novalis, Nguyễn Thái Ngọc Duy
In-Reply-To: <20170213152011.12050-1-pclouds@gmail.com>
This centralizes all path rewriting of files-backend.c in one place so
we have easier time removing the path rewriting later. There could be
some hidden indirect git_path() though, I didn't audit the code to the
bottom.
Side note: set_worktree_head_symref() is a bad boy and should not be in
files-backend.c (probably should not exist in the first place). But
we'll leave it there until we have better multi-worktree support in refs
before we update it.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
refs/files-backend.c | 193 ++++++++++++++++++++++++++-------------------------
1 file changed, 98 insertions(+), 95 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 39217a2ca..c69e4fe84 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -165,12 +165,13 @@ static struct ref_entry *create_dir_entry(struct files_ref_store *ref_store,
const char *dirname, size_t len,
int incomplete);
static void add_entry_to_dir(struct ref_dir *dir, struct ref_entry *entry);
-static int files_log_ref_write(const char *refname, const unsigned char *old_sha1,
+static int files_log_ref_write(struct files_ref_store *refs,
+ const char *refname, const unsigned char *old_sha1,
const unsigned char *new_sha1, const char *msg,
int flags, struct strbuf *err);
-void files_path(struct files_ref_store *refs, struct strbuf *sb,
- const char *fmt, ...) __attribute__((format (printf, 3, 4)));
+static void files_path(struct files_ref_store *refs, struct strbuf *sb,
+ const char *fmt, ...) __attribute__((format (printf, 3, 4)));
static struct ref_dir *get_ref_dir(struct ref_entry *entry)
{
@@ -933,8 +934,8 @@ struct files_ref_store {
/* Lock used for the main packed-refs file: */
static struct lock_file packlock;
-void files_path(struct files_ref_store *refs, struct strbuf *sb,
- const char *fmt, ...)
+static void files_path(struct files_ref_store *refs, struct strbuf *sb,
+ const char *fmt, ...)
{
struct strbuf tmp = STRBUF_INIT;
va_list vap;
@@ -1180,12 +1181,10 @@ static void read_packed_refs(FILE *f, struct ref_dir *dir)
static struct packed_ref_cache *get_packed_ref_cache(struct files_ref_store *refs)
{
char *packed_refs_file;
+ struct strbuf sb = STRBUF_INIT;
- if (refs->submodule)
- packed_refs_file = git_pathdup_submodule(refs->submodule,
- "packed-refs");
- else
- packed_refs_file = git_pathdup("packed-refs");
+ files_path(refs, &sb, "packed-refs");
+ packed_refs_file = strbuf_detach(&sb, NULL);
if (refs->packed &&
!stat_validity_check(&refs->packed->validity, packed_refs_file))
@@ -1251,10 +1250,7 @@ static void read_loose_refs(const char *dirname, struct ref_dir *dir)
size_t path_baselen;
int err = 0;
- if (refs->submodule)
- err = strbuf_git_path_submodule(&path, refs->submodule, "%s", dirname);
- else
- strbuf_git_path(&path, "%s", dirname);
+ files_path(refs, &path, "%s", dirname);
path_baselen = path.len;
if (err) {
@@ -1396,10 +1392,7 @@ static int files_read_raw_ref(struct ref_store *ref_store,
*type = 0;
strbuf_reset(&sb_path);
- if (refs->submodule)
- strbuf_git_path_submodule(&sb_path, refs->submodule, "%s", refname);
- else
- strbuf_git_path(&sb_path, "%s", refname);
+ files_path(refs, &sb_path, "%s", refname);
path = sb_path.buf;
@@ -1587,7 +1580,7 @@ static int lock_raw_ref(struct files_ref_store *refs,
*lock_p = lock = xcalloc(1, sizeof(*lock));
lock->ref_name = xstrdup(refname);
- strbuf_git_path(&ref_file, "%s", refname);
+ files_path(refs, &ref_file, "%s", refname);
retry:
switch (safe_create_leading_directories(ref_file.buf)) {
@@ -2054,7 +2047,7 @@ static struct ref_lock *lock_ref_sha1_basic(struct files_ref_store *refs,
if (flags & REF_DELETING)
resolve_flags |= RESOLVE_REF_ALLOW_BAD_NAME;
- strbuf_git_path(&ref_file, "%s", refname);
+ files_path(refs, &ref_file, "%s", refname);
resolved = !!resolve_ref_unsafe(refname, resolve_flags,
lock->old_oid.hash, type);
if (!resolved && errno == EISDIR) {
@@ -2199,7 +2192,7 @@ static int lock_packed_refs(struct files_ref_store *refs, int flags)
timeout_configured = 1;
}
- strbuf_git_path(&sb, "packed-refs");
+ files_path(refs, &sb, "packed-refs");
ret = hold_lock_file_for_update_timeout(&packlock, sb.buf,
flags, timeout_value);
strbuf_release(&sb);
@@ -2345,7 +2338,7 @@ static int pack_if_possible_fn(struct ref_entry *entry, void *cb_data)
* Remove empty parents, but spare refs/ and immediate subdirs.
* Note: munges *name.
*/
-static void try_remove_empty_parents(char *name)
+static void try_remove_empty_parents(struct files_ref_store *refs, char *name)
{
char *p, *q;
int i;
@@ -2370,7 +2363,7 @@ static void try_remove_empty_parents(char *name)
if (q == p)
break;
*q = '\0';
- strbuf_git_path(&sb, "%s", name);
+ files_path(refs, &sb, "%s", name);
ret = rmdir(sb.buf);
strbuf_release(&sb);
if (ret)
@@ -2379,7 +2372,7 @@ static void try_remove_empty_parents(char *name)
}
/* make sure nobody touched the ref, and unlink */
-static void prune_ref(struct ref_to_prune *r)
+static void prune_ref(struct files_ref_store *refs, struct ref_to_prune *r)
{
struct ref_transaction *transaction;
struct strbuf err = STRBUF_INIT;
@@ -2399,13 +2392,13 @@ static void prune_ref(struct ref_to_prune *r)
}
ref_transaction_free(transaction);
strbuf_release(&err);
- try_remove_empty_parents(r->name);
+ try_remove_empty_parents(refs, r->name);
}
-static void prune_refs(struct ref_to_prune *r)
+static void prune_refs(struct files_ref_store *refs, struct ref_to_prune *r)
{
while (r) {
- prune_ref(r);
+ prune_ref(refs, r);
r = r->next;
}
}
@@ -2428,7 +2421,7 @@ static int files_pack_refs(struct ref_store *ref_store, unsigned int flags)
if (commit_packed_refs(refs))
die_errno("unable to overwrite old ref-pack file");
- prune_refs(cbdata.ref_to_prune);
+ prune_refs(refs, cbdata.ref_to_prune);
return 0;
}
@@ -2464,7 +2457,7 @@ static int repack_without_refs(struct files_ref_store *refs,
if (lock_packed_refs(refs, 0)) {
struct strbuf sb = STRBUF_INIT;
- strbuf_git_path(&sb, "packed-refs");
+ files_path(refs, &sb, "packed-refs");
unable_to_lock_message(sb.buf, errno, err);
strbuf_release(&sb);
return -1;
@@ -2560,15 +2553,15 @@ static int files_delete_refs(struct ref_store *ref_store,
*/
#define TMP_RENAMED_LOG "logs/refs/.tmp-renamed-log"
-static int rename_tmp_log(const char *newrefname)
+static int rename_tmp_log(struct files_ref_store *refs, const char *newrefname)
{
int attempts_remaining = 4;
struct strbuf path = STRBUF_INIT;
struct strbuf tmp_renamed_log = STRBUF_INIT;
int ret = -1;
- strbuf_git_path(&path, "logs/%s", newrefname);
- strbuf_git_path(&tmp_renamed_log, TMP_RENAMED_LOG);
+ files_path(refs, &path, "logs/%s", newrefname);
+ files_path(refs, &tmp_renamed_log, TMP_RENAMED_LOG);
retry:
switch (safe_create_leading_directories_const(path.buf)) {
case SCLD_OK:
@@ -2657,7 +2650,7 @@ static int files_rename_ref(struct ref_store *ref_store,
int log, ret;
struct strbuf err = STRBUF_INIT;
- strbuf_git_path(&sb_oldref, "logs/%s", oldrefname);
+ files_path(refs, &sb_oldref, "logs/%s", oldrefname);
log = !lstat(sb_oldref.buf, &loginfo);
strbuf_release(&sb_oldref);
if (log && S_ISLNK(loginfo.st_mode))
@@ -2673,8 +2666,8 @@ static int files_rename_ref(struct ref_store *ref_store,
if (!rename_ref_available(oldrefname, newrefname))
return 1;
- strbuf_git_path(&sb_oldref, "logs/%s", oldrefname);
- strbuf_git_path(&tmp_renamed_log, TMP_RENAMED_LOG);
+ files_path(refs, &sb_oldref, "logs/%s", oldrefname);
+ files_path(refs, &tmp_renamed_log, TMP_RENAMED_LOG);
ret = log && rename(sb_oldref.buf, tmp_renamed_log.buf);
strbuf_release(&sb_oldref);
strbuf_release(&tmp_renamed_log);
@@ -2701,7 +2694,7 @@ static int files_rename_ref(struct ref_store *ref_store,
struct strbuf path = STRBUF_INIT;
int result;
- strbuf_git_path(&path, "%s", newrefname);
+ files_path(refs, &path, "%s", newrefname);
result = remove_empty_directories(&path);
strbuf_release(&path);
@@ -2715,7 +2708,7 @@ static int files_rename_ref(struct ref_store *ref_store,
}
}
- if (log && rename_tmp_log(newrefname))
+ if (log && rename_tmp_log(refs, newrefname))
goto rollback;
logmoved = log;
@@ -2757,12 +2750,12 @@ static int files_rename_ref(struct ref_store *ref_store,
log_all_ref_updates = flag;
rollbacklog:
- strbuf_git_path(&sb_newref, "logs/%s", newrefname);
- strbuf_git_path(&sb_oldref, "logs/%s", oldrefname);
+ files_path(refs, &sb_newref, "logs/%s", newrefname);
+ files_path(refs, &sb_oldref, "logs/%s", oldrefname);
if (logmoved && rename(sb_newref.buf, sb_oldref.buf))
error("unable to restore logfile %s from %s: %s",
oldrefname, newrefname, strerror(errno));
- strbuf_git_path(&tmp_renamed_log, TMP_RENAMED_LOG);
+ files_path(refs, &tmp_renamed_log, TMP_RENAMED_LOG);
if (!logmoved && log &&
rename(tmp_renamed_log.buf, sb_oldref.buf))
error("unable to restore logfile %s from "TMP_RENAMED_LOG": %s",
@@ -2818,11 +2811,13 @@ static int commit_ref(struct ref_lock *lock)
* should_autocreate_reflog returns non-zero. Otherwise, create it
* regardless of the ref name. Fill in *err and return -1 on failure.
*/
-static int log_ref_setup(const char *refname, struct strbuf *logfile, struct strbuf *err, int force_create)
+static int log_ref_setup(struct files_ref_store *refs, const char *refname,
+ struct strbuf *logfile, struct strbuf *err,
+ int force_create)
{
int logfd, oflags = O_APPEND | O_WRONLY;
- strbuf_git_path(logfile, "logs/%s", refname);
+ files_path(refs, logfile, "logs/%s", refname);
if (force_create || should_autocreate_reflog(refname)) {
if (safe_create_leading_directories(logfile->buf) < 0) {
strbuf_addf(err, "unable to create directory for '%s': "
@@ -2865,11 +2860,10 @@ static int files_create_reflog(struct ref_store *ref_store,
{
int ret;
struct strbuf sb = STRBUF_INIT;
+ struct files_ref_store *refs =
+ files_downcast(ref_store, 0, "create_reflog");
- /* Check validity (but we don't need the result): */
- files_downcast(ref_store, 0, "create_reflog");
-
- ret = log_ref_setup(refname, &sb, err, force_create);
+ ret = log_ref_setup(refs, refname, &sb, err, force_create);
strbuf_release(&sb);
return ret;
}
@@ -2900,7 +2894,8 @@ static int log_ref_write_fd(int fd, const unsigned char *old_sha1,
return 0;
}
-static int log_ref_write_1(const char *refname, const unsigned char *old_sha1,
+static int log_ref_write_1(struct files_ref_store *refs,
+ const char *refname, const unsigned char *old_sha1,
const unsigned char *new_sha1, const char *msg,
struct strbuf *logfile, int flags,
struct strbuf *err)
@@ -2910,7 +2905,7 @@ static int log_ref_write_1(const char *refname, const unsigned char *old_sha1,
if (log_all_ref_updates < 0)
log_all_ref_updates = !is_bare_repository();
- result = log_ref_setup(refname, logfile, err, flags & REF_FORCE_CREATE_REFLOG);
+ result = log_ref_setup(refs, refname, logfile, err, flags & REF_FORCE_CREATE_REFLOG);
if (result)
return result;
@@ -2934,21 +2929,23 @@ static int log_ref_write_1(const char *refname, const unsigned char *old_sha1,
return 0;
}
-static int log_ref_write(const char *refname, const unsigned char *old_sha1,
+static int log_ref_write(struct files_ref_store *refs,
+ const char *refname, const unsigned char *old_sha1,
const unsigned char *new_sha1, const char *msg,
int flags, struct strbuf *err)
{
- return files_log_ref_write(refname, old_sha1, new_sha1, msg, flags,
- err);
+ return files_log_ref_write(refs, refname, old_sha1, new_sha1,
+ msg, flags, err);
}
-int files_log_ref_write(const char *refname, const unsigned char *old_sha1,
+int files_log_ref_write(struct files_ref_store *refs,
+ const char *refname, const unsigned char *old_sha1,
const unsigned char *new_sha1, const char *msg,
int flags, struct strbuf *err)
{
struct strbuf sb = STRBUF_INIT;
- int ret = log_ref_write_1(refname, old_sha1, new_sha1, msg, &sb, flags,
- err);
+ int ret = log_ref_write_1(refs, refname, old_sha1, new_sha1, msg,
+ &sb, flags, err);
strbuf_release(&sb);
return ret;
}
@@ -3005,7 +3002,8 @@ static int commit_ref_update(struct files_ref_store *refs,
files_assert_main_repository(refs, "commit_ref_update");
clear_loose_ref_cache(refs);
- if (log_ref_write(lock->ref_name, lock->old_oid.hash, sha1, logmsg, 0, err)) {
+ if (log_ref_write(refs, lock->ref_name, lock->old_oid.hash,
+ sha1, logmsg, 0, err)) {
char *old_msg = strbuf_detach(err, NULL);
strbuf_addf(err, "cannot update the ref '%s': %s",
lock->ref_name, old_msg);
@@ -3036,8 +3034,8 @@ static int commit_ref_update(struct files_ref_store *refs,
if (head_ref && (head_flag & REF_ISSYMREF) &&
!strcmp(head_ref, lock->ref_name)) {
struct strbuf log_err = STRBUF_INIT;
- if (log_ref_write("HEAD", lock->old_oid.hash, sha1,
- logmsg, 0, &log_err)) {
+ if (log_ref_write(refs, "HEAD", lock->old_oid.hash,
+ sha1, logmsg, 0, &log_err)) {
error("%s", log_err.buf);
strbuf_release(&log_err);
}
@@ -3069,23 +3067,26 @@ static int create_ref_symlink(struct ref_lock *lock, const char *target)
return ret;
}
-static void update_symref_reflog(struct ref_lock *lock, const char *refname,
+static void update_symref_reflog(struct files_ref_store *refs,
+ struct ref_lock *lock, const char *refname,
const char *target, const char *logmsg)
{
struct strbuf err = STRBUF_INIT;
unsigned char new_sha1[20];
if (logmsg && !read_ref(target, new_sha1) &&
- log_ref_write(refname, lock->old_oid.hash, new_sha1, logmsg, 0, &err)) {
+ log_ref_write(refs, refname, lock->old_oid.hash,
+ new_sha1, logmsg, 0, &err)) {
error("%s", err.buf);
strbuf_release(&err);
}
}
-static int create_symref_locked(struct ref_lock *lock, const char *refname,
+static int create_symref_locked(struct files_ref_store *refs,
+ struct ref_lock *lock, const char *refname,
const char *target, const char *logmsg)
{
if (prefer_symlink_refs && !create_ref_symlink(lock, target)) {
- update_symref_reflog(lock, refname, target, logmsg);
+ update_symref_reflog(refs, lock, refname, target, logmsg);
return 0;
}
@@ -3093,7 +3094,7 @@ static int create_symref_locked(struct ref_lock *lock, const char *refname,
return error("unable to fdopen %s: %s",
lock->lk->tempfile.filename.buf, strerror(errno));
- update_symref_reflog(lock, refname, target, logmsg);
+ update_symref_reflog(refs, lock, refname, target, logmsg);
/* no error check; commit_ref will check ferror */
fprintf(lock->lk->tempfile.fp, "ref: %s\n", target);
@@ -3122,13 +3123,19 @@ static int files_create_symref(struct ref_store *ref_store,
return -1;
}
- ret = create_symref_locked(lock, refname, target, logmsg);
+ ret = create_symref_locked(refs, lock, refname, target, logmsg);
unlock_ref(lock);
return ret;
}
int set_worktree_head_symref(const char *gitdir, const char *target)
{
+ /*
+ * FIXME: this obviously will not work well for future refs
+ * backends. This function needs to die.
+ */
+ struct files_ref_store *refs =
+ files_downcast(get_ref_store(NULL), 0, "set_head_symref");
static struct lock_file head_lock;
struct ref_lock *lock;
struct strbuf head_path = STRBUF_INIT;
@@ -3155,7 +3162,7 @@ int set_worktree_head_symref(const char *gitdir, const char *target)
lock->lk = &head_lock;
lock->ref_name = xstrdup(head_rel);
- ret = create_symref_locked(lock, head_rel, target, NULL);
+ ret = create_symref_locked(refs, lock, head_rel, target, NULL);
unlock_ref(lock); /* will free lock */
strbuf_release(&head_path);
@@ -3165,14 +3172,13 @@ int set_worktree_head_symref(const char *gitdir, const char *target)
static int files_reflog_exists(struct ref_store *ref_store,
const char *refname)
{
+ struct files_ref_store *refs =
+ files_downcast(ref_store, 0, "reflog_exists");
struct strbuf sb = STRBUF_INIT;
struct stat st;
int ret;
- /* Check validity (but we don't need the result): */
- files_downcast(ref_store, 0, "reflog_exists");
-
- strbuf_git_path(&sb, "logs/%s", refname);
+ files_path(refs, &sb, "logs/%s", refname);
ret = !lstat(sb.buf, &st) && S_ISREG(st.st_mode);
strbuf_release(&sb);
return ret;
@@ -3181,13 +3187,12 @@ static int files_reflog_exists(struct ref_store *ref_store,
static int files_delete_reflog(struct ref_store *ref_store,
const char *refname)
{
+ struct files_ref_store *refs =
+ files_downcast(ref_store, 0, "delete_reflog");
struct strbuf sb = STRBUF_INIT;
int ret;
- /* Check validity (but we don't need the result): */
- files_downcast(ref_store, 0, "delete_reflog");
-
- strbuf_git_path(&sb, "logs/%s", refname);
+ files_path(refs, &sb, "logs/%s", refname);
ret = remove_path(sb.buf);
strbuf_release(&sb);
return ret;
@@ -3237,15 +3242,14 @@ static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store,
each_reflog_ent_fn fn,
void *cb_data)
{
+ struct files_ref_store *refs =
+ files_downcast(ref_store, 0, "for_each_reflog_ent_reverse");
struct strbuf sb = STRBUF_INIT;
FILE *logfp;
long pos;
int ret = 0, at_tail = 1;
- /* Check validity (but we don't need the result): */
- files_downcast(ref_store, 0, "for_each_reflog_ent_reverse");
-
- strbuf_git_path(&sb, "logs/%s", refname);
+ files_path(refs, &sb, "logs/%s", refname);
logfp = fopen(sb.buf, "r");
strbuf_release(&sb);
if (!logfp)
@@ -3346,14 +3350,13 @@ static int files_for_each_reflog_ent(struct ref_store *ref_store,
const char *refname,
each_reflog_ent_fn fn, void *cb_data)
{
+ struct files_ref_store *refs =
+ files_downcast(ref_store, 0, "for_each_reflog_ent");
FILE *logfp;
struct strbuf sb = STRBUF_INIT;
int ret = 0;
- /* Check validity (but we don't need the result): */
- files_downcast(ref_store, 0, "for_each_reflog_ent");
-
- strbuf_git_path(&sb, "logs/%s", refname);
+ files_path(refs, &sb, "logs/%s", refname);
logfp = fopen(sb.buf, "r");
strbuf_release(&sb);
if (!logfp)
@@ -3435,15 +3438,14 @@ static struct ref_iterator_vtable files_reflog_iterator_vtable = {
static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_store)
{
+ struct files_ref_store *refs =
+ files_downcast(ref_store, 0, "reflog_iterator_begin");
struct files_reflog_iterator *iter = xcalloc(1, sizeof(*iter));
struct ref_iterator *ref_iterator = &iter->base;
struct strbuf sb = STRBUF_INIT;
- /* Check validity (but we don't need the result): */
- files_downcast(ref_store, 0, "reflog_iterator_begin");
-
base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable);
- strbuf_git_path(&sb, "logs");
+ files_path(refs, &sb, "logs");
iter->dir_iterator = dir_iterator_begin(sb.buf);
strbuf_release(&sb);
return ref_iterator;
@@ -3867,8 +3869,8 @@ static int files_transaction_commit(struct ref_store *ref_store,
if (update->flags & REF_NEEDS_COMMIT ||
update->flags & REF_LOG_ONLY) {
- if (log_ref_write(lock->ref_name, lock->old_oid.hash,
- update->new_sha1,
+ if (log_ref_write(refs, lock->ref_name,
+ lock->old_oid.hash, update->new_sha1,
update->msg, update->flags, err)) {
char *old_msg = strbuf_detach(err, NULL);
@@ -3917,7 +3919,7 @@ static int files_transaction_commit(struct ref_store *ref_store,
for_each_string_list_item(ref_to_delete, &refs_to_delete) {
struct strbuf sb = STRBUF_INIT;
- strbuf_git_path(&sb, "logs/%s", ref_to_delete->string);
+ files_path(refs, &sb, "logs/%s", ref_to_delete->string);
unlink_or_warn(sb.buf);
strbuf_release(&sb);
}
@@ -4079,6 +4081,7 @@ static int files_reflog_expire(struct ref_store *ref_store,
int status = 0;
int type;
struct strbuf err = STRBUF_INIT;
+ struct strbuf sb = STRBUF_INIT;
memset(&cb, 0, sizeof(cb));
cb.flags = flags;
@@ -4103,7 +4106,8 @@ static int files_reflog_expire(struct ref_store *ref_store,
return 0;
}
- log_file = git_pathdup("logs/%s", refname);
+ files_path(refs, &sb, "logs/%s", refname);
+ log_file = strbuf_detach(&sb, NULL);
if (!(flags & EXPIRE_REFLOGS_DRY_RUN)) {
/*
* Even though holding $GIT_DIR/logs/$reflog.lock has
@@ -4174,25 +4178,24 @@ static int files_reflog_expire(struct ref_store *ref_store,
static int files_init_db(struct ref_store *ref_store, struct strbuf *err)
{
+ struct files_ref_store *refs =
+ files_downcast(ref_store, 0, "init_db");
struct strbuf sb = STRBUF_INIT;
- /* Check validity (but we don't need the result): */
- files_downcast(ref_store, 0, "init_db");
-
/*
* Create .git/refs/{heads,tags}
*/
- strbuf_git_path(&sb, "refs/heads");
+ files_path(refs, &sb, "refs/heads");
safe_create_dir(sb.buf, 1);
strbuf_reset(&sb);
- strbuf_git_path(&sb, "refs/tags");
+ files_path(refs, &sb, "refs/tags");
safe_create_dir(sb.buf, 1);
strbuf_reset(&sb);
if (get_shared_repository()) {
- strbuf_git_path(&sb, "refs/heads");
+ files_path(refs, &sb, "refs/heads");
adjust_shared_perm(sb.buf);
strbuf_reset(&sb);
- strbuf_git_path(&sb, "refs/tags");
+ files_path(refs, &sb, "refs/tags");
adjust_shared_perm(sb.buf);
}
strbuf_release(&sb);
--
2.11.0.157.gd943d85
^ permalink raw reply related
* [PATCH 06/11] refs-internal.h: correct is_per_worktree_ref()
From: Nguyễn Thái Ngọc Duy @ 2017-02-13 15:20 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Michael Haggerty, Johannes Schindelin, sbeller,
novalis, Nguyễn Thái Ngọc Duy
In-Reply-To: <20170213152011.12050-1-pclouds@gmail.com>
All refs outside refs/ directory is per-worktree, not just HEAD.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
refs/refs-internal.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index f4aed49f5..69d02b6ba 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -653,7 +653,7 @@ const char *resolve_ref_recursively(struct ref_store *refs,
static inline int is_per_worktree_ref(const char *refname)
{
- return !strcmp(refname, "HEAD") ||
+ return !starts_with(refname, "refs/") ||
starts_with(refname, "refs/bisect/");
}
--
2.11.0.157.gd943d85
^ permalink raw reply related
* [PATCH 07/11] files-backend: remove the use of git_path()
From: Nguyễn Thái Ngọc Duy @ 2017-02-13 15:20 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Michael Haggerty, Johannes Schindelin, sbeller,
novalis, Nguyễn Thái Ngọc Duy
In-Reply-To: <20170213152011.12050-1-pclouds@gmail.com>
Given $GIT_DIR and $GIT_COMMON_DIR, files-backend is now in charge of
deciding what goes where. The end goal is to pass $GIT_DIR only. A
refs "view" of a linked worktree is a logical ref store that combines
two files backends together.
(*) Not entirely true since strbuf_git_path_submodule() still does path
translation underneath. But that's for another patch.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
refs/files-backend.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index c69e4fe84..50eb9edb6 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -927,6 +927,9 @@ struct files_ref_store {
*/
const char *submodule;
+ struct strbuf gitdir;
+ struct strbuf gitcommondir;
+
struct ref_entry *loose;
struct packed_ref_cache *packed;
};
@@ -939,6 +942,7 @@ static void files_path(struct files_ref_store *refs, struct strbuf *sb,
{
struct strbuf tmp = STRBUF_INIT;
va_list vap;
+ const char *ref;
va_start(vap, fmt);
strbuf_vaddf(&tmp, fmt, vap);
@@ -946,8 +950,12 @@ static void files_path(struct files_ref_store *refs, struct strbuf *sb,
if (refs->submodule)
strbuf_git_path_submodule(sb, refs->submodule,
"%s", tmp.buf);
+ else if (is_per_worktree_ref(tmp.buf) ||
+ (skip_prefix(tmp.buf, "logs/", &ref) &&
+ is_per_worktree_ref(ref)))
+ strbuf_addf(sb, "%s/%s", refs->gitdir.buf, tmp.buf);
else
- strbuf_git_path(sb, "%s", tmp.buf);
+ strbuf_addf(sb, "%s/%s", refs->gitcommondir.buf, tmp.buf);
strbuf_release(&tmp);
}
@@ -1006,7 +1014,15 @@ static struct ref_store *files_ref_store_create(const char *submodule)
base_ref_store_init(ref_store, &refs_be_files);
- refs->submodule = xstrdup_or_null(submodule);
+ strbuf_init(&refs->gitdir, 0);
+ strbuf_init(&refs->gitcommondir, 0);
+
+ if (submodule) {
+ refs->submodule = xstrdup_or_null(submodule);
+ } else {
+ strbuf_addstr(&refs->gitdir, get_git_dir());
+ strbuf_addstr(&refs->gitcommondir, get_git_common_dir());
+ }
return ref_store;
}
--
2.11.0.157.gd943d85
^ permalink raw reply related
* [PATCH 05/11] refs.c: share is_per_worktree_ref() to files-backend.c
From: Nguyễn Thái Ngọc Duy @ 2017-02-13 15:20 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Michael Haggerty, Johannes Schindelin, sbeller,
novalis, Nguyễn Thái Ngọc Duy
In-Reply-To: <20170213152011.12050-1-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
refs.c | 6 ------
refs/refs-internal.h | 6 ++++++
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/refs.c b/refs.c
index f03dcf58b..2cacd934e 100644
--- a/refs.c
+++ b/refs.c
@@ -489,12 +489,6 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log)
return logs_found;
}
-static int is_per_worktree_ref(const char *refname)
-{
- return !strcmp(refname, "HEAD") ||
- starts_with(refname, "refs/bisect/");
-}
-
static int is_pseudoref_syntax(const char *refname)
{
const char *c;
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 59e65958a..f4aed49f5 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -651,4 +651,10 @@ const char *resolve_ref_recursively(struct ref_store *refs,
int resolve_flags,
unsigned char *sha1, int *flags);
+static inline int is_per_worktree_ref(const char *refname)
+{
+ return !strcmp(refname, "HEAD") ||
+ starts_with(refname, "refs/bisect/");
+}
+
#endif /* REFS_REFS_INTERNAL_H */
--
2.11.0.157.gd943d85
^ permalink raw reply related
* [PATCH 09/11] refs: move submodule code out of files-backend.c
From: Nguyễn Thái Ngọc Duy @ 2017-02-13 15:20 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Michael Haggerty, Johannes Schindelin, sbeller,
novalis, Nguyễn Thái Ngọc Duy
In-Reply-To: <20170213152011.12050-1-pclouds@gmail.com>
files-backend is now initialized with a $GIT_DIR. Converting a submodule
path to where real submodule gitdir is located is done in get_ref_store().
The new code in init_submodule_ref_store() is basically a copy of
strbuf_git_path_submodule().
This gives a slight performance improvement for submodules since we
don't convert submodule path to gitdir at every backend call like
before. We pay that once at ref-store creation.
More cleanup in files_downcast() follows shortly. It's separate to keep
noises from this patch.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
refs.c | 48 +++++++++++++++++++++++++++++++++++++++++-------
refs/files-backend.c | 25 +++++++------------------
refs/refs-internal.h | 6 +++---
3 files changed, 51 insertions(+), 28 deletions(-)
diff --git a/refs.c b/refs.c
index 8ef7a52ba..9ac194945 100644
--- a/refs.c
+++ b/refs.c
@@ -9,6 +9,7 @@
#include "refs/refs-internal.h"
#include "object.h"
#include "tag.h"
+#include "submodule-config.h"
/*
* List of all available backends
@@ -1410,7 +1411,7 @@ static void register_ref_store(struct ref_store *refs, const char *submodule)
* Create, record, and return a ref_store instance for the specified
* submodule (or the main repository if submodule is NULL).
*/
-static struct ref_store *ref_store_init(const char *submodule)
+static struct ref_store *ref_store_init(const char *submodule, const char *gitdir)
{
const char *be_name = "files";
struct ref_storage_be *be = find_ref_storage_backend(be_name);
@@ -1419,7 +1420,7 @@ static struct ref_store *ref_store_init(const char *submodule)
if (!be)
die("BUG: reference backend %s is unknown", be_name);
- refs = be->init(submodule);
+ refs = be->init(gitdir);
register_ref_store(refs, submodule);
return refs;
}
@@ -1445,15 +1446,48 @@ static struct ref_store *lookup_ref_store(const char *submodule)
return entry ? entry->refs : NULL;
}
-static struct ref_store *init_submodule_ref_store(const char *submodule)
+static struct ref_store *init_submodule_ref_store(const char *path)
{
struct strbuf submodule_sb = STRBUF_INIT;
+ struct strbuf git_submodule_common_dir = STRBUF_INIT;
+ struct strbuf git_submodule_dir = STRBUF_INIT;
+ struct strbuf buf = STRBUF_INIT;
+ const char *git_dir;
+ const struct submodule *sub;
struct ref_store *refs = NULL;
- strbuf_addstr(&submodule_sb, submodule);
- if (is_nonbare_repository_dir(&submodule_sb))
- refs = ref_store_init(submodule);
+ strbuf_addstr(&submodule_sb, path);
+ if (!is_nonbare_repository_dir(&submodule_sb))
+ goto done;
+
+ strbuf_addstr(&buf, path);
+ strbuf_complete(&buf, '/');
+ strbuf_addstr(&buf, ".git");
+
+ git_dir = read_gitfile(buf.buf);
+ if (git_dir) {
+ strbuf_reset(&buf);
+ strbuf_addstr(&buf, git_dir);
+ }
+ if (!is_git_directory(buf.buf)) {
+ gitmodules_config();
+ sub = submodule_from_path(null_sha1, path);
+ if (!sub)
+ goto done;
+ strbuf_reset(&buf);
+ strbuf_git_path(&buf, "%s/%s", "modules", sub->name);
+ }
+ strbuf_addch(&buf, '/');
+ strbuf_addbuf(&git_submodule_dir, &buf);
+
+ refs = ref_store_init(path, git_submodule_dir.buf);
+
+done:
+ strbuf_release(&git_submodule_dir);
+ strbuf_release(&git_submodule_common_dir);
strbuf_release(&submodule_sb);
+ strbuf_release(&buf);
+
return refs;
}
@@ -1465,7 +1499,7 @@ struct ref_store *get_ref_store(const char *submodule)
refs = lookup_ref_store(NULL);
if (!refs)
- refs = ref_store_init(NULL);
+ refs = ref_store_init(NULL, NULL);
} else {
refs = lookup_ref_store(submodule);
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 50eb9edb6..834bc6fdf 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -920,13 +920,6 @@ struct packed_ref_cache {
struct files_ref_store {
struct ref_store base;
- /*
- * The name of the submodule represented by this object, or
- * NULL if it represents the main repository's reference
- * store:
- */
- const char *submodule;
-
struct strbuf gitdir;
struct strbuf gitcommondir;
@@ -947,12 +940,9 @@ static void files_path(struct files_ref_store *refs, struct strbuf *sb,
va_start(vap, fmt);
strbuf_vaddf(&tmp, fmt, vap);
va_end(vap);
- if (refs->submodule)
- strbuf_git_path_submodule(sb, refs->submodule,
- "%s", tmp.buf);
- else if (is_per_worktree_ref(tmp.buf) ||
- (skip_prefix(tmp.buf, "logs/", &ref) &&
- is_per_worktree_ref(ref)))
+ if (is_per_worktree_ref(tmp.buf) ||
+ (skip_prefix(tmp.buf, "logs/", &ref) &&
+ is_per_worktree_ref(ref)))
strbuf_addf(sb, "%s/%s", refs->gitdir.buf, tmp.buf);
else
strbuf_addf(sb, "%s/%s", refs->gitcommondir.buf, tmp.buf);
@@ -1007,7 +997,7 @@ static void clear_loose_ref_cache(struct files_ref_store *refs)
* Create a new submodule ref cache and add it to the internal
* set of caches.
*/
-static struct ref_store *files_ref_store_create(const char *submodule)
+static struct ref_store *files_ref_store_create(const char *gitdir)
{
struct files_ref_store *refs = xcalloc(1, sizeof(*refs));
struct ref_store *ref_store = (struct ref_store *)refs;
@@ -1017,8 +1007,9 @@ static struct ref_store *files_ref_store_create(const char *submodule)
strbuf_init(&refs->gitdir, 0);
strbuf_init(&refs->gitcommondir, 0);
- if (submodule) {
- refs->submodule = xstrdup_or_null(submodule);
+ if (gitdir) {
+ strbuf_addstr(&refs->gitdir, gitdir);
+ get_common_dir_noenv(&refs->gitcommondir, gitdir);
} else {
strbuf_addstr(&refs->gitdir, get_git_dir());
strbuf_addstr(&refs->gitcommondir, get_git_common_dir());
@@ -1034,8 +1025,6 @@ static struct ref_store *files_ref_store_create(const char *submodule)
static void files_assert_main_repository(struct files_ref_store *refs,
const char *caller)
{
- if (refs->submodule)
- die("BUG: %s called for a submodule", caller);
}
/*
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 69d02b6ba..d7112770d 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -476,12 +476,12 @@ struct ref_store;
/* refs backends */
/*
- * Initialize the ref_store for the specified submodule, or for the
- * main repository if submodule == NULL. These functions should call
+ * Initialize the ref_store for the specified gitdir, or for the
+ * current repository if gitdir == NULL. These functions should call
* base_ref_store_init() to initialize the shared part of the
* ref_store and to record the ref_store for later lookup.
*/
-typedef struct ref_store *ref_store_init_fn(const char *submodule);
+typedef struct ref_store *ref_store_init_fn(const char *gitdir);
typedef int ref_init_db_fn(struct ref_store *refs, struct strbuf *err);
--
2.11.0.157.gd943d85
^ permalink raw reply related
* [PATCH 10/11] files-backend: remove submodule_allowed from files_downcast()
From: Nguyễn Thái Ngọc Duy @ 2017-02-13 15:20 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Michael Haggerty, Johannes Schindelin, sbeller,
novalis, Nguyễn Thái Ngọc Duy
In-Reply-To: <20170213152011.12050-1-pclouds@gmail.com>
Since submodule or not is irrelevant to files-backend after the last
patch, remove the parameter from files_downcast() and kill
files_assert_main_repository().
PS. This implies that all ref operations are allowed for submodules. But
we may need to look more closely to see if that's really true...
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
refs/files-backend.c | 69 ++++++++++++++++------------------------------------
1 file changed, 21 insertions(+), 48 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 834bc6fdf..2fb270b6f 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1019,23 +1019,13 @@ static struct ref_store *files_ref_store_create(const char *gitdir)
}
/*
- * Die if refs is for a submodule (i.e., not for the main repository).
- * caller is used in any necessary error messages.
- */
-static void files_assert_main_repository(struct files_ref_store *refs,
- const char *caller)
-{
-}
-
-/*
* Downcast ref_store to files_ref_store. Die if ref_store is not a
* files_ref_store. If submodule_allowed is not true, then also die if
* files_ref_store is for a submodule (i.e., not for the main
* repository). caller is used in any necessary error messages.
*/
-static struct files_ref_store *files_downcast(
- struct ref_store *ref_store, int submodule_allowed,
- const char *caller)
+static struct files_ref_store *files_downcast(struct ref_store *ref_store,
+ const char *caller)
{
struct files_ref_store *refs;
@@ -1045,9 +1035,6 @@ static struct files_ref_store *files_downcast(
refs = (struct files_ref_store *)ref_store;
- if (!submodule_allowed)
- files_assert_main_repository(refs, caller);
-
return refs;
}
@@ -1383,7 +1370,7 @@ static int files_read_raw_ref(struct ref_store *ref_store,
struct strbuf *referent, unsigned int *type)
{
struct files_ref_store *refs =
- files_downcast(ref_store, 1, "read_raw_ref");
+ files_downcast(ref_store, "read_raw_ref");
struct strbuf sb_contents = STRBUF_INIT;
struct strbuf sb_path = STRBUF_INIT;
const char *path;
@@ -1576,7 +1563,6 @@ static int lock_raw_ref(struct files_ref_store *refs,
int ret = TRANSACTION_GENERIC_ERROR;
assert(err);
- files_assert_main_repository(refs, "lock_raw_ref");
*type = 0;
@@ -1800,7 +1786,7 @@ static enum peel_status peel_entry(struct ref_entry *entry, int repeel)
static int files_peel_ref(struct ref_store *ref_store,
const char *refname, unsigned char *sha1)
{
- struct files_ref_store *refs = files_downcast(ref_store, 0, "peel_ref");
+ struct files_ref_store *refs = files_downcast(ref_store, "peel_ref");
int flag;
unsigned char base[20];
@@ -1909,7 +1895,7 @@ static struct ref_iterator *files_ref_iterator_begin(
const char *prefix, unsigned int flags)
{
struct files_ref_store *refs =
- files_downcast(ref_store, 1, "ref_iterator_begin");
+ files_downcast(ref_store, "ref_iterator_begin");
struct ref_dir *loose_dir, *packed_dir;
struct ref_iterator *loose_iter, *packed_iter;
struct files_ref_iterator *iter;
@@ -2042,7 +2028,6 @@ static struct ref_lock *lock_ref_sha1_basic(struct files_ref_store *refs,
int attempts_remaining = 3;
int resolved;
- files_assert_main_repository(refs, "lock_ref_sha1_basic");
assert(err);
lock = xcalloc(1, sizeof(struct ref_lock));
@@ -2190,8 +2175,6 @@ static int lock_packed_refs(struct files_ref_store *refs, int flags)
struct strbuf sb = STRBUF_INIT;
int ret;
- files_assert_main_repository(refs, "lock_packed_refs");
-
if (!timeout_configured) {
git_config_get_int("core.packedrefstimeout", &timeout_value);
timeout_configured = 1;
@@ -2231,8 +2214,6 @@ static int commit_packed_refs(struct files_ref_store *refs)
int save_errno = 0;
FILE *out;
- files_assert_main_repository(refs, "commit_packed_refs");
-
if (!packed_ref_cache->lock)
die("internal error: packed-refs not locked");
@@ -2264,8 +2245,6 @@ static void rollback_packed_refs(struct files_ref_store *refs)
struct packed_ref_cache *packed_ref_cache =
get_packed_ref_cache(refs);
- files_assert_main_repository(refs, "rollback_packed_refs");
-
if (!packed_ref_cache->lock)
die("internal error: packed-refs not locked");
rollback_lock_file(packed_ref_cache->lock);
@@ -2411,7 +2390,7 @@ static void prune_refs(struct files_ref_store *refs, struct ref_to_prune *r)
static int files_pack_refs(struct ref_store *ref_store, unsigned int flags)
{
struct files_ref_store *refs =
- files_downcast(ref_store, 0, "pack_refs");
+ files_downcast(ref_store, "pack_refs");
struct pack_refs_cb_data cbdata;
memset(&cbdata, 0, sizeof(cbdata));
@@ -2444,7 +2423,6 @@ static int repack_without_refs(struct files_ref_store *refs,
struct string_list_item *refname;
int ret, needs_repacking = 0, removed = 0;
- files_assert_main_repository(refs, "repack_without_refs");
assert(err);
/* Look for a packed ref */
@@ -2512,7 +2490,7 @@ static int files_delete_refs(struct ref_store *ref_store,
struct string_list *refnames, unsigned int flags)
{
struct files_ref_store *refs =
- files_downcast(ref_store, 0, "delete_refs");
+ files_downcast(ref_store, "delete_refs");
struct strbuf err = STRBUF_INIT;
int i, result = 0;
@@ -2619,7 +2597,7 @@ static int files_verify_refname_available(struct ref_store *ref_store,
struct strbuf *err)
{
struct files_ref_store *refs =
- files_downcast(ref_store, 1, "verify_refname_available");
+ files_downcast(ref_store, "verify_refname_available");
struct ref_dir *packed_refs = get_packed_refs(refs);
struct ref_dir *loose_refs = get_loose_refs(refs);
@@ -2644,7 +2622,7 @@ static int files_rename_ref(struct ref_store *ref_store,
const char *logmsg)
{
struct files_ref_store *refs =
- files_downcast(ref_store, 0, "rename_ref");
+ files_downcast(ref_store, "rename_ref");
unsigned char sha1[20], orig_sha1[20];
int flag = 0, logmoved = 0;
struct ref_lock *lock;
@@ -2866,7 +2844,7 @@ static int files_create_reflog(struct ref_store *ref_store,
int ret;
struct strbuf sb = STRBUF_INIT;
struct files_ref_store *refs =
- files_downcast(ref_store, 0, "create_reflog");
+ files_downcast(ref_store, "create_reflog");
ret = log_ref_setup(refs, refname, &sb, err, force_create);
strbuf_release(&sb);
@@ -3004,8 +2982,6 @@ static int commit_ref_update(struct files_ref_store *refs,
const unsigned char *sha1, const char *logmsg,
struct strbuf *err)
{
- files_assert_main_repository(refs, "commit_ref_update");
-
clear_loose_ref_cache(refs);
if (log_ref_write(refs, lock->ref_name, lock->old_oid.hash,
sha1, logmsg, 0, err)) {
@@ -3114,7 +3090,7 @@ static int files_create_symref(struct ref_store *ref_store,
const char *logmsg)
{
struct files_ref_store *refs =
- files_downcast(ref_store, 0, "create_symref");
+ files_downcast(ref_store, "create_symref");
struct strbuf err = STRBUF_INIT;
struct ref_lock *lock;
int ret;
@@ -3140,7 +3116,7 @@ int set_worktree_head_symref(const char *gitdir, const char *target)
* backends. This function needs to die.
*/
struct files_ref_store *refs =
- files_downcast(get_ref_store(NULL), 0, "set_head_symref");
+ files_downcast(get_ref_store(NULL), "set_head_symref");
static struct lock_file head_lock;
struct ref_lock *lock;
struct strbuf head_path = STRBUF_INIT;
@@ -3178,7 +3154,7 @@ static int files_reflog_exists(struct ref_store *ref_store,
const char *refname)
{
struct files_ref_store *refs =
- files_downcast(ref_store, 0, "reflog_exists");
+ files_downcast(ref_store, "reflog_exists");
struct strbuf sb = STRBUF_INIT;
struct stat st;
int ret;
@@ -3193,7 +3169,7 @@ static int files_delete_reflog(struct ref_store *ref_store,
const char *refname)
{
struct files_ref_store *refs =
- files_downcast(ref_store, 0, "delete_reflog");
+ files_downcast(ref_store, "delete_reflog");
struct strbuf sb = STRBUF_INIT;
int ret;
@@ -3248,7 +3224,7 @@ static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store,
void *cb_data)
{
struct files_ref_store *refs =
- files_downcast(ref_store, 0, "for_each_reflog_ent_reverse");
+ files_downcast(ref_store, "for_each_reflog_ent_reverse");
struct strbuf sb = STRBUF_INIT;
FILE *logfp;
long pos;
@@ -3356,7 +3332,7 @@ static int files_for_each_reflog_ent(struct ref_store *ref_store,
each_reflog_ent_fn fn, void *cb_data)
{
struct files_ref_store *refs =
- files_downcast(ref_store, 0, "for_each_reflog_ent");
+ files_downcast(ref_store, "for_each_reflog_ent");
FILE *logfp;
struct strbuf sb = STRBUF_INIT;
int ret = 0;
@@ -3444,7 +3420,7 @@ static struct ref_iterator_vtable files_reflog_iterator_vtable = {
static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_store)
{
struct files_ref_store *refs =
- files_downcast(ref_store, 0, "reflog_iterator_begin");
+ files_downcast(ref_store, "reflog_iterator_begin");
struct files_reflog_iterator *iter = xcalloc(1, sizeof(*iter));
struct ref_iterator *ref_iterator = &iter->base;
struct strbuf sb = STRBUF_INIT;
@@ -3656,8 +3632,6 @@ static int lock_ref_for_update(struct files_ref_store *refs,
int ret;
struct ref_lock *lock;
- files_assert_main_repository(refs, "lock_ref_for_update");
-
if ((update->flags & REF_HAVE_NEW) && is_null_sha1(update->new_sha1))
update->flags |= REF_DELETING;
@@ -3782,7 +3756,7 @@ static int files_transaction_commit(struct ref_store *ref_store,
struct strbuf *err)
{
struct files_ref_store *refs =
- files_downcast(ref_store, 0, "ref_transaction_commit");
+ files_downcast(ref_store, "ref_transaction_commit");
int ret = 0, i;
struct string_list refs_to_delete = STRING_LIST_INIT_NODUP;
struct string_list_item *ref_to_delete;
@@ -3956,7 +3930,7 @@ static int files_initial_transaction_commit(struct ref_store *ref_store,
struct strbuf *err)
{
struct files_ref_store *refs =
- files_downcast(ref_store, 0, "initial_ref_transaction_commit");
+ files_downcast(ref_store, "initial_ref_transaction_commit");
int ret = 0, i;
struct string_list affected_refnames = STRING_LIST_INIT_NODUP;
@@ -4078,7 +4052,7 @@ static int files_reflog_expire(struct ref_store *ref_store,
void *policy_cb_data)
{
struct files_ref_store *refs =
- files_downcast(ref_store, 0, "reflog_expire");
+ files_downcast(ref_store, "reflog_expire");
static struct lock_file reflog_lock;
struct expire_reflog_cb cb;
struct ref_lock *lock;
@@ -4183,8 +4157,7 @@ static int files_reflog_expire(struct ref_store *ref_store,
static int files_init_db(struct ref_store *ref_store, struct strbuf *err)
{
- struct files_ref_store *refs =
- files_downcast(ref_store, 0, "init_db");
+ struct files_ref_store *refs = files_downcast(ref_store, "init_db");
struct strbuf sb = STRBUF_INIT;
/*
--
2.11.0.157.gd943d85
^ permalink raw reply related
* [PATCH 11/11] refs: split and make get_*_ref_store() public API
From: Nguyễn Thái Ngọc Duy @ 2017-02-13 15:20 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Michael Haggerty, Johannes Schindelin, sbeller,
novalis, Nguyễn Thái Ngọc Duy
In-Reply-To: <20170213152011.12050-1-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
refs.c | 59 ++++++++++++++++++++++++++++++----------------------
refs.h | 13 ++++++++++++
refs/files-backend.c | 2 +-
refs/refs-internal.h | 12 -----------
4 files changed, 48 insertions(+), 38 deletions(-)
diff --git a/refs.c b/refs.c
index 9ac194945..48350da87 100644
--- a/refs.c
+++ b/refs.c
@@ -1160,7 +1160,7 @@ int head_ref(each_ref_fn fn, void *cb_data)
static int do_for_each_ref(const char *submodule, const char *prefix,
each_ref_fn fn, int trim, int flags, void *cb_data)
{
- struct ref_store *refs = get_ref_store(submodule);
+ struct ref_store *refs = get_submodule_ref_store(submodule);
struct ref_iterator *iter;
if (!refs)
@@ -1304,7 +1304,7 @@ const char *resolve_ref_recursively(struct ref_store *refs,
/* backend functions */
int refs_init_db(struct strbuf *err)
{
- struct ref_store *refs = get_ref_store(NULL);
+ struct ref_store *refs = get_main_ref_store();
return refs->be->init_db(refs, err);
}
@@ -1312,7 +1312,7 @@ int refs_init_db(struct strbuf *err)
const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
unsigned char *sha1, int *flags)
{
- return resolve_ref_recursively(get_ref_store(NULL), refname,
+ return resolve_ref_recursively(get_main_ref_store(), refname,
resolve_flags, sha1, flags);
}
@@ -1333,10 +1333,10 @@ int resolve_gitlink_ref(const char *submodule, const char *refname,
/* We need to strip off one or more trailing slashes */
char *stripped = xmemdupz(submodule, len);
- refs = get_ref_store(stripped);
+ refs = get_submodule_ref_store(stripped);
free(stripped);
} else {
- refs = get_ref_store(submodule);
+ refs = get_submodule_ref_store(submodule);
}
if (!refs)
@@ -1491,15 +1491,24 @@ static struct ref_store *init_submodule_ref_store(const char *path)
return refs;
}
-struct ref_store *get_ref_store(const char *submodule)
+struct ref_store *get_main_ref_store(void)
{
struct ref_store *refs;
- if (!submodule || !*submodule) {
- refs = lookup_ref_store(NULL);
+ refs = lookup_ref_store(NULL);
- if (!refs)
- refs = ref_store_init(NULL, NULL);
+ if (!refs)
+ refs = ref_store_init(NULL, NULL);
+
+ return refs;
+}
+
+struct ref_store *get_submodule_ref_store(const char *submodule)
+{
+ struct ref_store *refs;
+
+ if (!submodule || !*submodule) {
+ return get_main_ref_store();
} else {
refs = lookup_ref_store(submodule);
@@ -1519,14 +1528,14 @@ void base_ref_store_init(struct ref_store *refs,
/* backend functions */
int pack_refs(unsigned int flags)
{
- struct ref_store *refs = get_ref_store(NULL);
+ struct ref_store *refs = get_main_ref_store();
return refs->be->pack_refs(refs, flags);
}
int peel_ref(const char *refname, unsigned char *sha1)
{
- struct ref_store *refs = get_ref_store(NULL);
+ struct ref_store *refs = get_main_ref_store();
return refs->be->peel_ref(refs, refname, sha1);
}
@@ -1534,7 +1543,7 @@ int peel_ref(const char *refname, unsigned char *sha1)
int create_symref(const char *ref_target, const char *refs_heads_master,
const char *logmsg)
{
- struct ref_store *refs = get_ref_store(NULL);
+ struct ref_store *refs = get_main_ref_store();
return refs->be->create_symref(refs, ref_target, refs_heads_master,
logmsg);
@@ -1543,7 +1552,7 @@ int create_symref(const char *ref_target, const char *refs_heads_master,
int ref_transaction_commit(struct ref_transaction *transaction,
struct strbuf *err)
{
- struct ref_store *refs = get_ref_store(NULL);
+ struct ref_store *refs = get_main_ref_store();
return refs->be->transaction_commit(refs, transaction, err);
}
@@ -1553,14 +1562,14 @@ int verify_refname_available(const char *refname,
const struct string_list *skip,
struct strbuf *err)
{
- struct ref_store *refs = get_ref_store(NULL);
+ struct ref_store *refs = get_main_ref_store();
return refs->be->verify_refname_available(refs, refname, extra, skip, err);
}
int for_each_reflog(each_ref_fn fn, void *cb_data)
{
- struct ref_store *refs = get_ref_store(NULL);
+ struct ref_store *refs = get_main_ref_store();
struct ref_iterator *iter;
iter = refs->be->reflog_iterator_begin(refs);
@@ -1571,7 +1580,7 @@ int for_each_reflog(each_ref_fn fn, void *cb_data)
int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn,
void *cb_data)
{
- struct ref_store *refs = get_ref_store(NULL);
+ struct ref_store *refs = get_main_ref_store();
return refs->be->for_each_reflog_ent_reverse(refs, refname,
fn, cb_data);
@@ -1580,14 +1589,14 @@ int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn,
int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn,
void *cb_data)
{
- struct ref_store *refs = get_ref_store(NULL);
+ struct ref_store *refs = get_main_ref_store();
return refs->be->for_each_reflog_ent(refs, refname, fn, cb_data);
}
int reflog_exists(const char *refname)
{
- struct ref_store *refs = get_ref_store(NULL);
+ struct ref_store *refs = get_main_ref_store();
return refs->be->reflog_exists(refs, refname);
}
@@ -1595,14 +1604,14 @@ int reflog_exists(const char *refname)
int safe_create_reflog(const char *refname, int force_create,
struct strbuf *err)
{
- struct ref_store *refs = get_ref_store(NULL);
+ struct ref_store *refs = get_main_ref_store();
return refs->be->create_reflog(refs, refname, force_create, err);
}
int delete_reflog(const char *refname)
{
- struct ref_store *refs = get_ref_store(NULL);
+ struct ref_store *refs = get_main_ref_store();
return refs->be->delete_reflog(refs, refname);
}
@@ -1614,7 +1623,7 @@ int reflog_expire(const char *refname, const unsigned char *sha1,
reflog_expiry_cleanup_fn cleanup_fn,
void *policy_cb_data)
{
- struct ref_store *refs = get_ref_store(NULL);
+ struct ref_store *refs = get_main_ref_store();
return refs->be->reflog_expire(refs, refname, sha1, flags,
prepare_fn, should_prune_fn,
@@ -1624,21 +1633,21 @@ int reflog_expire(const char *refname, const unsigned char *sha1,
int initial_ref_transaction_commit(struct ref_transaction *transaction,
struct strbuf *err)
{
- struct ref_store *refs = get_ref_store(NULL);
+ struct ref_store *refs = get_main_ref_store();
return refs->be->initial_transaction_commit(refs, transaction, err);
}
int delete_refs(struct string_list *refnames, unsigned int flags)
{
- struct ref_store *refs = get_ref_store(NULL);
+ struct ref_store *refs = get_main_ref_store();
return refs->be->delete_refs(refs, refnames, flags);
}
int rename_ref(const char *oldref, const char *newref, const char *logmsg)
{
- struct ref_store *refs = get_ref_store(NULL);
+ struct ref_store *refs = get_main_ref_store();
return refs->be->rename_ref(refs, oldref, newref, logmsg);
}
diff --git a/refs.h b/refs.h
index 694784391..f5fba16c8 100644
--- a/refs.h
+++ b/refs.h
@@ -553,4 +553,17 @@ int reflog_expire(const char *refname, const unsigned char *sha1,
int ref_storage_backend_exists(const char *name);
+/*
+ * Return the ref_store instance for the specified submodule. For the
+ * main repository, use submodule==NULL; such a call cannot fail. For
+ * a submodule, the submodule must exist and be a nonbare repository,
+ * otherwise return NULL. If the requested reference store has not yet
+ * been initialized, initialize it first.
+ *
+ * For backwards compatibility, submodule=="" is treated the same as
+ * submodule==NULL.
+ */
+struct ref_store *get_submodule_ref_store(const char *submodule);
+struct ref_store *get_main_ref_store(void);
+
#endif /* REFS_H */
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 2fb270b6f..eab156733 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -3116,7 +3116,7 @@ int set_worktree_head_symref(const char *gitdir, const char *target)
* backends. This function needs to die.
*/
struct files_ref_store *refs =
- files_downcast(get_ref_store(NULL), "set_head_symref");
+ files_downcast(get_main_ref_store(), "set_head_symref");
static struct lock_file head_lock;
struct ref_lock *lock;
struct strbuf head_path = STRBUF_INIT;
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index d7112770d..cb6882779 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -634,18 +634,6 @@ struct ref_store {
void base_ref_store_init(struct ref_store *refs,
const struct ref_storage_be *be);
-/*
- * Return the ref_store instance for the specified submodule. For the
- * main repository, use submodule==NULL; such a call cannot fail. For
- * a submodule, the submodule must exist and be a nonbare repository,
- * otherwise return NULL. If the requested reference store has not yet
- * been initialized, initialize it first.
- *
- * For backwards compatibility, submodule=="" is treated the same as
- * submodule==NULL.
- */
-struct ref_store *get_ref_store(const char *submodule);
-
const char *resolve_ref_recursively(struct ref_store *refs,
const char *refname,
int resolve_flags,
--
2.11.0.157.gd943d85
^ permalink raw reply related
* [PATCH 08/11] refs.c: factor submodule code out of get_ref_store()
From: Nguyễn Thái Ngọc Duy @ 2017-02-13 15:20 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Michael Haggerty, Johannes Schindelin, sbeller,
novalis, Nguyễn Thái Ngọc Duy
In-Reply-To: <20170213152011.12050-1-pclouds@gmail.com>
This code is going to be expanded a bit soon. Keep it out for
better readability later.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
refs.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/refs.c b/refs.c
index 2cacd934e..8ef7a52ba 100644
--- a/refs.c
+++ b/refs.c
@@ -1445,6 +1445,18 @@ static struct ref_store *lookup_ref_store(const char *submodule)
return entry ? entry->refs : NULL;
}
+static struct ref_store *init_submodule_ref_store(const char *submodule)
+{
+ struct strbuf submodule_sb = STRBUF_INIT;
+ struct ref_store *refs = NULL;
+
+ strbuf_addstr(&submodule_sb, submodule);
+ if (is_nonbare_repository_dir(&submodule_sb))
+ refs = ref_store_init(submodule);
+ strbuf_release(&submodule_sb);
+ return refs;
+}
+
struct ref_store *get_ref_store(const char *submodule)
{
struct ref_store *refs;
@@ -1457,14 +1469,8 @@ struct ref_store *get_ref_store(const char *submodule)
} else {
refs = lookup_ref_store(submodule);
- if (!refs) {
- struct strbuf submodule_sb = STRBUF_INIT;
-
- strbuf_addstr(&submodule_sb, submodule);
- if (is_nonbare_repository_dir(&submodule_sb))
- refs = ref_store_init(submodule);
- strbuf_release(&submodule_sb);
- }
+ if (!refs)
+ refs = init_submodule_ref_store(submodule);
}
return refs;
--
2.11.0.157.gd943d85
^ permalink raw reply related
* Re: Bug in 'git describe' if I have two tags on the same commit.
From: Kevin Daudt @ 2017-02-13 15:44 UTC (permalink / raw)
To: Istvan Pato; +Cc: git
In-Reply-To: <CAOcUJQwnCJOhUUU2RqJP2H5YxUr4qCEpyDj_XiiQSe4V6rcBmg@mail.gmail.com>
On Sun, Feb 12, 2017 at 01:15:22PM +0100, Istvan Pato wrote:
> I didn't get back the latest tag by 'git describe --tags --always' if
> I have two tags on the same commit.
>
> // repository ppa:git-core/ppa
>
> (master)⚡ % cat /etc/lsb-release
> DISTRIB_ID=Ubuntu
> DISTRIB_RELEASE=16.04
> DISTRIB_CODENAME=xenial
> DISTRIB_DESCRIPTION="Ubuntu 16.04.2 LTS"
>
> (master)⚡ % git --version
> git version 2.11.0
>
> (master) [1] % git show-ref --tag
> 76c634390... refs/tags/1.0.0
> b77c7cd17... refs/tags/1.1.0
> b77c7cd17... refs/tags/1.2.0
>
> (master) % git describe --tags --always
> 1.1.0-1-ge9e9ced
>
> ### Expected: 1.2.0
>
> References:
>
> https://www.kernel.org/pub/software/scm/git/docs/RelNotes-1.7.1.1.txt
>
> * "git describe" did not tie-break tags that point at the same commit
> correctly; newer ones are preferred by paying attention to the
> tagger date now.
>
> http://stackoverflow.com/questions/8089002/git-describe-with-two-tags-on-the-same-commit
>
> Thanks,
> Istvan Pato
Are these lightweight tags? Only annotated tags have a date associated
to them, which is where the rel-notes refers to.
^ permalink raw reply
* Re: [PATCH] fixup! bisect--helper: `bisect_next_check` & bisect_voc shell function in C
From: Johannes Schindelin @ 2017-02-13 16:23 UTC (permalink / raw)
To: René Scharfe; +Cc: Pranit Bauva, git, Junio C Hamano
In-Reply-To: <128b4de6-7b8e-27b9-414d-c6c6529cb491@web.de>
[-- Attachment #1: Type: text/plain, Size: 1670 bytes --]
Hi René,
On Fri, 10 Feb 2017, René Scharfe wrote:
> Am 10.02.2017 um 15:20 schrieb Johannes Schindelin:
> > It is curious that only MacOSX builds trigger an error about this, both
> > GCC and Clang, but not Linux GCC nor Clang (see
> > https://travis-ci.org/git/git/jobs/200182819#L1152 for details):
> >
> > builtin/bisect--helper.c:299:6: error: variable 'good_syn' is used
> > uninitialized whenever 'if' condition is true
> > [-Werror,-Wsometimes-uninitialized]
> > if (missing_good && !missing_bad && current_term &&
> > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > builtin/bisect--helper.c:350:7: note: uninitialized use occurs here
> > if (!good_syn)
> > ^~~~~~~~
>
> The only way that good_syn could be used in the if block is by going to the
> label finish, which does the following before returning:
>
> if (!bad_ref)
> free(bad_ref);
> if (!good_glob)
> free(good_glob);
> if (!bad_syn)
> free(bad_syn);
> if (!good_syn)
> free(good_syn);
>
> On Linux that code is elided completely -- freeing NULL is a no-op. I guess
> free(3) has different attributes on OS X and compilers don't dare to optimize
> it away there.
>
> So instead of calling free(3) only in the case when we did not allocate memory
> (which makes no sense and leaks) we should either call it in the opposite
> case, or (preferred) unconditionally, as it can handle the NULL case itself.
> Once that's fixed initialization will be required even on Linux.
Exactly, free(NULL) is a no-op. The problem before this fixup was that
good_syn was not initialized to NULL.
Ciao,
Dscho
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox