* Re: Fixup of a fixup not working right
From: Philip Oakley @ 2016-09-04 11:47 UTC (permalink / raw)
To: Johannes Schindelin, Junio C Hamano; +Cc: Robert Dailey, Git
In-Reply-To: <alpine.DEB.2.20.1609040923390.129229@virtualbox>
From: "Johannes Schindelin" <Johannes.Schindelin@gmx.de>
> Hi Junio & Philip,
>
> On Fri, 2 Sep 2016, Junio C Hamano wrote:
>
>> "Philip Oakley" <philipoakley@iee.org> writes:
>>
>> > As I understand this it's implied by design. The issue is that the
>> > rebase is looking for that named commit within its current rebase
>> > range, and can't find it, so ignores it.
>> >
>> > There is a separate issue that all the fixup! fixup! messages are
>> > essentially treated as being concatenations of the original fixup!, no
>> > matter how many time the fiup is present.
>>
>> They can be handled separately, but they come from the same "design"
>> that could be improved. When the "original" is not in the range to
>> be rebased for whatever reason (including the most likely one, i.e.
>> it has already graduated to become part of the public history), the
>> best thing the user could do at that point may be, as you suggested
>> to Robert in your message, to turn the "fixup! original" that did
>> not make in time before "original" hit the public record into a
>> standalone "fix original" follow-up change, and then to squash
>> subsequent "fixup! fixup! original" (and other "fixup! original",
>> too) into that commit. And a good direction forward may be to see
>> if "rebase -i" can be taught to be more helpful for the user who
>> wants to do that.
>>
>> Perhaps a change like this to "rebase -i":
>>
>> - The search for "original" when handling "pick fixup! original",
>> when it does not find "original", could turn it into "reword
>> fixup! original" without changing its position in the instruction
>> sequence.
>>
>> - The search for "original" when handling "pick fixup! fixup!
>> original", could be (probably unconditionally) changed to look
>> for "fixup! original" to amend, instead of looking for "original"
>> as the current code (this is your "separate issue"). The same
>> "if the commit to be amended is not found, turn it into reword"
>> rule from the above applies to this one, too.
>>
>> may be an improvement?
>
> I would be *very* careful with such a change.
I agree about the need for care. The use case must be well understood.
> The point is that fixup! messages are really special, and are always
> intended to be squashed into the referenced commit *before* the latter
> hits `master`.
I think it's here that we have the hidden use case. I agree that all fixups
should be squashed before they hit the blessed golden repository.
I suspect that some use cases have intermediate repositories that contain a
'master' branch (it's just a name ;-) that isn't blessed and golden, e.g. at
the team review repo level. In such cases it is possible for a fixup! to be
passed up as part of the review, though it's not the current
norm/expectation.
>
> The entire design of the fixup! feature (using the commit subject as
> identifier, which is only "unique enough" in a topic branch that is still
> being developed) points to that.
>
> I am fairly certain that we would run into tons of problems if we diluted
> the concept of fixup! commits by changing the design so that fixup!
> commits all of a sudden become their own, "real" commits that can be fixed
> up themselves, as much of the current code simply does not expect that.
We already had that. the commit 22c5b13 (rebase -i: handle fixup! fixup!
in --autosquash, 2013-06-27) was an attempt to work around misunderstandings
about what fixed what.
In Robert's scenario (IIUC) that patch was too aggressive for the case where
the original commit is not part of the rebase. The patch lept in a little
too early in the processing so as to pretend that if it saw repeated "fixup!
" strings at the start of the messages it pretented there was only one, so
that they all applied in the original sequence.
I _think_ that the right approach would be to just bring such fixups
together in the to-do list ("as normal"), but still have the minimal common
commit message string still present, so that it would, in this case, still
have a resulting squashed commit that starts "!fixup ". It's important to be
moderately lenient to user choices - they may know something we don't, or at
least accept that their use case is 'unusual' [1]
>
> In short, I am opposed to this change.
It's not like G4W doesn't need fixup!s on the side branches e.g. 5eaffe9
("fixup! Handle new t1501 test case properly with MinGW", 2016-07-12)
> And even if I am overruled, I would strongly suggest to implement this on
> top of my rebase-i-extra branch (i.e. in the rebase--helper instead of the
> shell script) to avoid double churn.
I definitely agree there.
>
> Ciao,
> Johannes
>
--
Philip
[1] The removal of the "theirs" merge strategy is one I'd add to that list.
Calling it, for example, "reversed" would have kept it available while
reduced it's visibility. See http://marc.info/?l=git&m=121637513604413&w=2
^ permalink raw reply
* Re: [PATCH 1/6] git-gui: The term unified for remote in Japanese
From: Jakub Narębski @ 2016-09-04 12:10 UTC (permalink / raw)
To: Satoshi Yasushima, git; +Cc: Pat Thoyts
In-Reply-To: <1472913822-9088-1-git-send-email-s.yasushima@gmail.com>
W dniu 03.09.2016 o 16:43, Satoshi Yasushima pisze:
> msgid "Tracking branch %s is not a branch in the remote repository."
> -msgstr "トラッキング・ブランチ %s は遠隔リポジトリのブランチではありません。"
> +msgstr ""
What for is the above part of change (empty string)?
> +"トラッキング・ブランチ %s はリモートリポジトリのブランチではありません。"
--
Jakub Narębski
^ permalink raw reply
* [PATCH v2 06/38] add_packed_ref(): add a files_ref_store argument
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs/files-backend.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 439c500..c544de8 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1192,10 +1192,9 @@ static struct ref_dir *get_packed_refs(struct files_ref_store *refs)
* lock_packed_refs()). To actually write the packed-refs file, call
* commit_packed_refs().
*/
-static void add_packed_ref(const char *refname, const unsigned char *sha1)
+static void add_packed_ref(struct files_ref_store *refs,
+ const char *refname, const unsigned char *sha1)
{
- struct files_ref_store *refs =
- get_files_ref_store(NULL, "add_packed_ref");
struct packed_ref_cache *packed_ref_cache = get_packed_ref_cache(refs);
if (!packed_ref_cache->lock)
@@ -3879,6 +3878,8 @@ static int ref_present(const char *refname,
int initial_ref_transaction_commit(struct ref_transaction *transaction,
struct strbuf *err)
{
+ struct files_ref_store *refs =
+ get_files_ref_store(NULL, "initial_ref_transaction_commit");
int ret = 0, i;
struct string_list affected_refnames = STRING_LIST_INIT_NODUP;
@@ -3938,7 +3939,7 @@ int initial_ref_transaction_commit(struct ref_transaction *transaction,
if ((update->flags & REF_HAVE_NEW) &&
!is_null_sha1(update->new_sha1))
- add_packed_ref(update->refname, update->new_sha1);
+ add_packed_ref(refs, update->refname, update->new_sha1);
}
if (commit_packed_refs()) {
--
2.9.3
^ permalink raw reply related
* [PATCH v2 02/38] rename_ref_available(): add docstring
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, David Turner,
Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
From: David Turner <dturner@twopensource.com>
And improve the internal variable names.
Signed-off-by: David Turner <dturner@twopensource.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs.c | 12 ++++++------
refs/refs-internal.h | 12 +++++++++++-
2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/refs.c b/refs.c
index b4e7cac..4c609df 100644
--- a/refs.c
+++ b/refs.c
@@ -1081,20 +1081,20 @@ const char *find_descendant_ref(const char *dirname,
return NULL;
}
-int rename_ref_available(const char *oldname, const char *newname)
+int rename_ref_available(const char *old_refname, const char *new_refname)
{
struct string_list skip = STRING_LIST_INIT_NODUP;
struct strbuf err = STRBUF_INIT;
- int ret;
+ int ok;
- string_list_insert(&skip, oldname);
- ret = !verify_refname_available(newname, NULL, &skip, &err);
- if (!ret)
+ string_list_insert(&skip, old_refname);
+ ok = !verify_refname_available(new_refname, NULL, &skip, &err);
+ if (!ok)
error("%s", err.buf);
string_list_clear(&skip, 0);
strbuf_release(&err);
- return ret;
+ return ok;
}
int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index efe5847..0206e2b 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -240,7 +240,17 @@ const char *find_descendant_ref(const char *dirname,
const struct string_list *extras,
const struct string_list *skip);
-int rename_ref_available(const char *oldname, const char *newname);
+/*
+ * Check whether an attempt to rename old_refname to new_refname would
+ * cause a D/F conflict with any existing reference (other than
+ * possibly old_refname). If there would be a conflict, emit an error
+ * message and return false; otherwise, return true.
+ *
+ * Note that this function is not safe against all races with other
+ * processes (though rename_ref() catches some races that might get by
+ * this check).
+ */
+int rename_ref_available(const char *old_refname, const char *new_refname);
/* We allow "recursive" symbolic refs. Only within reason, though */
#define SYMREF_MAXDEPTH 5
--
2.9.3
^ permalink raw reply related
* [PATCH v2 01/38] resolve_gitlink_ref(): eliminate temporary variable
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs/files-backend.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 12290d2..74c2c47 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1387,7 +1387,7 @@ static int resolve_gitlink_ref_recursive(struct ref_cache *refs,
int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1)
{
- int len = strlen(path), retval;
+ int len = strlen(path);
struct strbuf submodule = STRBUF_INIT;
struct ref_cache *refs;
@@ -1404,8 +1404,7 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh
}
strbuf_release(&submodule);
- retval = resolve_gitlink_ref_recursive(refs, refname, sha1, 0);
- return retval;
+ return resolve_gitlink_ref_recursive(refs, refname, sha1, 0);
}
/*
--
2.9.3
^ permalink raw reply related
* [PATCH v2 04/38] refs: add a backend method structure
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, Ronnie Sahlberg,
David Turner, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
From: Ronnie Sahlberg <sahlberg@google.com>
Add a `struct ref_storage_be` to represent types of reference stores. In
OO notation, this is the class, and will soon hold some class
methods (e.g., a factory to create new ref_store instances) and will
also serve as the vtable for ref_store instances of that type.
As yet, the backends cannot do anything.
Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
Signed-off-by: David Turner <dturner@twopensource.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs.c | 19 +++++++++++++++++++
refs.h | 2 ++
refs/files-backend.c | 5 +++++
refs/refs-internal.h | 8 ++++++++
4 files changed, 34 insertions(+)
diff --git a/refs.c b/refs.c
index 4c609df..d2a29bb 100644
--- a/refs.c
+++ b/refs.c
@@ -10,6 +10,25 @@
#include "tag.h"
/*
+ * List of all available backends
+ */
+static struct ref_storage_be *refs_backends = &refs_be_files;
+
+static struct ref_storage_be *find_ref_storage_backend(const char *name)
+{
+ struct ref_storage_be *be;
+ for (be = refs_backends; be; be = be->next)
+ if (!strcmp(be->name, name))
+ return be;
+ return NULL;
+}
+
+int ref_storage_backend_exists(const char *name)
+{
+ return find_ref_storage_backend(name) != NULL;
+}
+
+/*
* How to handle various characters in refnames:
* 0: An acceptable character for refs
* 1: End-of-component
diff --git a/refs.h b/refs.h
index 1b02043..9a29f1b 100644
--- a/refs.h
+++ b/refs.h
@@ -544,4 +544,6 @@ int reflog_expire(const char *refname, const unsigned char *sha1,
reflog_expiry_cleanup_fn cleanup_fn,
void *policy_cb_data);
+int ref_storage_backend_exists(const char *name);
+
#endif /* REFS_H */
diff --git a/refs/files-backend.c b/refs/files-backend.c
index aa09586..ecf66e6 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -4076,3 +4076,8 @@ int reflog_expire(const char *refname, const unsigned char *sha1,
unlock_ref(lock);
return -1;
}
+
+struct ref_storage_be refs_be_files = {
+ NULL,
+ "files"
+};
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 0206e2b..2c9d134 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -525,4 +525,12 @@ int do_for_each_ref_iterator(struct ref_iterator *iter,
int read_raw_ref(const char *refname, unsigned char *sha1,
struct strbuf *referent, unsigned int *type);
+/* refs backends */
+struct ref_storage_be {
+ struct ref_storage_be *next;
+ const char *name;
+};
+
+extern struct ref_storage_be refs_be_files;
+
#endif /* REFS_REFS_INTERNAL_H */
--
2.9.3
^ permalink raw reply related
* [PATCH v2 07/38] get_packed_ref(): add a files_ref_store argument
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs/files-backend.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index c544de8..2fc8ec9 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1403,11 +1403,9 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh
* Return the ref_entry for the given refname from the packed
* references. If it does not exist, return NULL.
*/
-static struct ref_entry *get_packed_ref(const char *refname)
+static struct ref_entry *get_packed_ref(struct files_ref_store *refs,
+ const char *refname)
{
- struct files_ref_store *refs =
- get_files_ref_store(NULL, "get_packed_ref");
-
return find_ref(get_packed_refs(refs), refname);
}
@@ -1418,13 +1416,16 @@ static int resolve_missing_loose_ref(const char *refname,
unsigned char *sha1,
unsigned int *flags)
{
+ struct files_ref_store *refs =
+ get_files_ref_store(NULL, "resolve_missing_loose_ref");
+
struct ref_entry *entry;
/*
* The loose reference file does not exist; check for a packed
* reference.
*/
- entry = get_packed_ref(refname);
+ entry = get_packed_ref(refs, refname);
if (entry) {
hashcpy(sha1, entry->u.value.oid.hash);
*flags |= REF_ISPACKED;
@@ -1836,6 +1837,7 @@ static enum peel_status peel_entry(struct ref_entry *entry, int repeel)
int peel_ref(const char *refname, unsigned char *sha1)
{
+ struct files_ref_store *refs = get_files_ref_store(NULL, "peel_ref");
int flag;
unsigned char base[20];
@@ -1860,7 +1862,7 @@ int peel_ref(const char *refname, unsigned char *sha1)
* have REF_KNOWS_PEELED.
*/
if (flag & REF_ISPACKED) {
- struct ref_entry *r = get_packed_ref(refname);
+ struct ref_entry *r = get_packed_ref(refs, refname);
if (r) {
if (peel_entry(r, 0))
return -1;
@@ -2469,7 +2471,7 @@ static int repack_without_refs(struct string_list *refnames, struct strbuf *err)
/* Look for a packed ref */
for_each_string_list_item(refname, refnames) {
- if (get_packed_ref(refname->string)) {
+ if (get_packed_ref(refs, refname->string)) {
needs_repacking = 1;
break;
}
--
2.9.3
^ permalink raw reply related
* [PATCH v2 14/38] read_raw_ref(): take a (struct ref_store *) argument
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
And make the function work for submodules.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs.c | 4 +++-
refs/files-backend.c | 18 +++++++++++++-----
refs/refs-internal.h | 9 ++++++---
3 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/refs.c b/refs.c
index 9475844..9e6b005 100644
--- a/refs.c
+++ b/refs.c
@@ -1222,6 +1222,7 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
static struct strbuf sb_refname = STRBUF_INIT;
int unused_flags;
int symref_count;
+ struct ref_store *refs = get_ref_store(NULL);
if (!flags)
flags = &unused_flags;
@@ -1249,7 +1250,8 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
for (symref_count = 0; symref_count < SYMREF_MAXDEPTH; symref_count++) {
unsigned int read_flags = 0;
- if (read_raw_ref(refname, sha1, &sb_refname, &read_flags)) {
+ if (read_raw_ref(refs, refname,
+ sha1, &sb_refname, &read_flags)) {
*flags |= read_flags;
if (errno != ENOENT || (resolve_flags & RESOLVE_REF_READING))
return NULL;
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 3b0c837..ce6fe94 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1349,11 +1349,12 @@ static int resolve_packed_ref(struct files_ref_store *refs,
return -1;
}
-int read_raw_ref(const char *refname, unsigned char *sha1,
+int read_raw_ref(struct ref_store *ref_store,
+ const char *refname, unsigned char *sha1,
struct strbuf *referent, unsigned int *type)
{
struct files_ref_store *refs =
- get_files_ref_store(NULL, "read_raw_ref");
+ files_downcast(ref_store, 1, "read_raw_ref");
struct strbuf sb_contents = STRBUF_INIT;
struct strbuf sb_path = STRBUF_INIT;
const char *path;
@@ -1365,7 +1366,12 @@ int read_raw_ref(const char *refname, unsigned char *sha1,
*type = 0;
strbuf_reset(&sb_path);
- strbuf_git_path(&sb_path, "%s", refname);
+
+ if (*refs->base.submodule)
+ strbuf_git_path_submodule(&sb_path, refs->base.submodule, "%s", refname);
+ else
+ strbuf_git_path(&sb_path, "%s", refname);
+
path = sb_path.buf;
stat_ref:
@@ -1592,8 +1598,9 @@ static int lock_raw_ref(const char *refname, int mustexist,
unsigned int *type,
struct strbuf *err)
{
+ struct ref_store *ref_store = get_ref_store(NULL);
struct files_ref_store *refs =
- get_files_ref_store(NULL, "lock_raw_ref");
+ files_downcast(ref_store, 0, "lock_raw_ref");
struct ref_lock *lock;
struct strbuf ref_file = STRBUF_INIT;
int attempts_remaining = 3;
@@ -1683,7 +1690,8 @@ static int lock_raw_ref(const char *refname, int mustexist,
* fear that its value will change.
*/
- if (read_raw_ref(refname, lock->old_oid.hash, referent, type)) {
+ if (read_raw_ref(ref_store, refname,
+ lock->old_oid.hash, referent, type)) {
if (errno == ENOENT) {
if (mustexist) {
/* Garden variety missing reference. */
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index b7367ab..fa41d51 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -484,9 +484,11 @@ extern struct ref_iterator *current_ref_iter;
int do_for_each_ref_iterator(struct ref_iterator *iter,
each_ref_fn fn, void *cb_data);
+struct ref_store;
+
/*
- * Read the specified reference from the filesystem or packed refs
- * file, non-recursively. Set type to describe the reference, and:
+ * Read a reference from the specified reference store, non-recursively.
+ * Set type to describe the reference, and:
*
* - If refname is the name of a normal reference, fill in sha1
* (leaving referent unchanged).
@@ -522,7 +524,8 @@ int do_for_each_ref_iterator(struct ref_iterator *iter,
* - in all other cases, referent will be untouched, and therefore
* refname will still be valid and unchanged.
*/
-int read_raw_ref(const char *refname, unsigned char *sha1,
+int read_raw_ref(struct ref_store *ref_store,
+ const char *refname, unsigned char *sha1,
struct strbuf *referent, unsigned int *type);
/* refs backends */
--
2.9.3
^ permalink raw reply related
* [PATCH v2 10/38] refs: add a transaction_commit() method
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, Ronnie Sahlberg,
David Turner, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
From: Ronnie Sahlberg <sahlberg@google.com>
Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
Signed-off-by: David Turner <dturner@twopensource.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs.c | 9 +++++++++
refs/files-backend.c | 10 ++++++----
refs/refs-internal.h | 5 +++++
3 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/refs.c b/refs.c
index 9d6bcb1..9475844 100644
--- a/refs.c
+++ b/refs.c
@@ -1377,3 +1377,12 @@ void assert_main_repository(struct ref_store *refs, const char *caller)
if (*refs->submodule)
die("BUG: %s called for a submodule", caller);
}
+
+/* backend functions */
+int ref_transaction_commit(struct ref_transaction *transaction,
+ struct strbuf *err)
+{
+ struct ref_store *refs = get_ref_store(NULL);
+
+ return refs->be->transaction_commit(refs, transaction, err);
+}
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 6913d45..d896052 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -3710,11 +3710,12 @@ static int lock_ref_for_update(struct ref_update *update,
return 0;
}
-int ref_transaction_commit(struct ref_transaction *transaction,
- struct strbuf *err)
+static int files_transaction_commit(struct ref_store *ref_store,
+ struct ref_transaction *transaction,
+ struct strbuf *err)
{
struct files_ref_store *refs =
- get_files_ref_store(NULL, "ref_transaction_commit");
+ files_downcast(ref_store, 0, "ref_transaction_commit");
int ret = 0, i;
struct string_list refs_to_delete = STRING_LIST_INIT_NODUP;
struct string_list_item *ref_to_delete;
@@ -4103,5 +4104,6 @@ int reflog_expire(const char *refname, const unsigned char *sha1,
struct ref_storage_be refs_be_files = {
NULL,
"files",
- files_ref_store_create
+ files_ref_store_create,
+ files_transaction_commit
};
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index b952038..b7367ab 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -535,10 +535,15 @@ int read_raw_ref(const char *refname, unsigned char *sha1,
*/
typedef struct ref_store *ref_store_init_fn(const char *submodule);
+typedef int ref_transaction_commit_fn(struct ref_store *refs,
+ struct ref_transaction *transaction,
+ struct strbuf *err);
+
struct ref_storage_be {
struct ref_storage_be *next;
const char *name;
ref_store_init_fn *init;
+ ref_transaction_commit_fn *transaction_commit;
};
extern struct ref_storage_be refs_be_files;
--
2.9.3
^ permalink raw reply related
* [PATCH v2 03/38] refs: rename struct ref_cache to files_ref_store
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
The greater goal of this patch series is to develop the concept of a
reference store, which is a place that references, their values, and
their reflogs are stored, and to virtualize the reference interface so
that different types of ref_stores can be implemented. We will then, for
example, use ref_store instances to access submodule references and
worktree references.
Currently, we keep a ref_cache for each submodule that has had its
references iterated over. It is a far cry from a ref_store, but they are
stored the way we will want to store ref_stores, and ref_stores will
eventually have to hold the reference caches. So let's treat ref_caches
as embryo ref_stores, and build them out from there.
As the first step, simply rename `ref_cache` to `files_ref_store`, and
rename some functions and attributes correspondingly.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs/files-backend.c | 126 +++++++++++++++++++++++++--------------------------
1 file changed, 63 insertions(+), 63 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 74c2c47..aa09586 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -39,7 +39,7 @@ struct ref_value {
struct object_id peeled;
};
-struct ref_cache;
+struct files_ref_store;
/*
* Information used (along with the information in ref_entry) to
@@ -78,8 +78,8 @@ struct ref_dir {
*/
int sorted;
- /* A pointer to the ref_cache that contains this ref_dir. */
- struct ref_cache *ref_cache;
+ /* A pointer to the files_ref_store that contains this ref_dir. */
+ struct files_ref_store *ref_store;
struct ref_entry **entries;
};
@@ -161,7 +161,7 @@ struct ref_entry {
static void read_loose_refs(const char *dirname, struct ref_dir *dir);
static int search_ref_dir(struct ref_dir *dir, const char *refname, size_t len);
-static struct ref_entry *create_dir_entry(struct ref_cache *ref_cache,
+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);
@@ -183,7 +183,7 @@ static struct ref_dir *get_ref_dir(struct ref_entry *entry)
int pos = search_ref_dir(dir, "refs/bisect/", 12);
if (pos < 0) {
struct ref_entry *child_entry;
- child_entry = create_dir_entry(dir->ref_cache,
+ child_entry = create_dir_entry(dir->ref_store,
"refs/bisect/",
12, 1);
add_entry_to_dir(dir, child_entry);
@@ -261,13 +261,13 @@ static void clear_ref_dir(struct ref_dir *dir)
* dirname is the name of the directory with a trailing slash (e.g.,
* "refs/heads/") or "" for the top-level directory.
*/
-static struct ref_entry *create_dir_entry(struct ref_cache *ref_cache,
+static struct ref_entry *create_dir_entry(struct files_ref_store *ref_store,
const char *dirname, size_t len,
int incomplete)
{
struct ref_entry *direntry;
FLEX_ALLOC_MEM(direntry, name, dirname, len);
- direntry->u.subdir.ref_cache = ref_cache;
+ direntry->u.subdir.ref_store = ref_store;
direntry->flag = REF_DIR | (incomplete ? REF_INCOMPLETE : 0);
return direntry;
}
@@ -343,7 +343,7 @@ static struct ref_dir *search_for_subdir(struct ref_dir *dir,
* therefore, create an empty record for it but mark
* the record complete.
*/
- entry = create_dir_entry(dir->ref_cache, subdirname, len, 0);
+ entry = create_dir_entry(dir->ref_store, subdirname, len, 0);
add_entry_to_dir(dir, entry);
} else {
entry = dir->entries[entry_index];
@@ -887,9 +887,9 @@ struct packed_ref_cache {
/*
* Count of references to the data structure in this instance,
- * including the pointer from ref_cache::packed if any. The
- * data will not be freed as long as the reference count is
- * nonzero.
+ * including the pointer from files_ref_store::packed if any.
+ * The data will not be freed as long as the reference count
+ * is nonzero.
*/
unsigned int referrers;
@@ -910,17 +910,17 @@ struct packed_ref_cache {
* Future: need to be in "struct repository"
* when doing a full libification.
*/
-static struct ref_cache {
- struct ref_cache *next;
+static struct files_ref_store {
+ struct files_ref_store *next;
struct ref_entry *loose;
struct packed_ref_cache *packed;
/*
- * The submodule name, or "" for the main repo. We allocate
- * length 1 rather than FLEX_ARRAY so that the main ref_cache
- * is initialized correctly.
+ * The submodule name, or "" for the main repo. We allocate
+ * length 1 rather than FLEX_ARRAY so that the main
+ * files_ref_store is initialized correctly.
*/
char name[1];
-} ref_cache, *submodule_ref_caches;
+} ref_store, *submodule_ref_stores;
/* Lock used for the main packed-refs file: */
static struct lock_file packlock;
@@ -949,7 +949,7 @@ static int release_packed_ref_cache(struct packed_ref_cache *packed_refs)
}
}
-static void clear_packed_ref_cache(struct ref_cache *refs)
+static void clear_packed_ref_cache(struct files_ref_store *refs)
{
if (refs->packed) {
struct packed_ref_cache *packed_refs = refs->packed;
@@ -961,7 +961,7 @@ static void clear_packed_ref_cache(struct ref_cache *refs)
}
}
-static void clear_loose_ref_cache(struct ref_cache *refs)
+static void clear_loose_ref_cache(struct files_ref_store *refs)
{
if (refs->loose) {
free_ref_entry(refs->loose);
@@ -973,32 +973,32 @@ static void clear_loose_ref_cache(struct ref_cache *refs)
* Create a new submodule ref cache and add it to the internal
* set of caches.
*/
-static struct ref_cache *create_ref_cache(const char *submodule)
+static struct files_ref_store *create_ref_store(const char *submodule)
{
- struct ref_cache *refs;
+ struct files_ref_store *refs;
if (!submodule)
submodule = "";
FLEX_ALLOC_STR(refs, name, submodule);
- refs->next = submodule_ref_caches;
- submodule_ref_caches = refs;
+ refs->next = submodule_ref_stores;
+ submodule_ref_stores = refs;
return refs;
}
-static struct ref_cache *lookup_ref_cache(const char *submodule)
+static struct files_ref_store *lookup_ref_store(const char *submodule)
{
- struct ref_cache *refs;
+ struct files_ref_store *refs;
if (!submodule || !*submodule)
- return &ref_cache;
+ return &ref_store;
- for (refs = submodule_ref_caches; refs; refs = refs->next)
+ for (refs = submodule_ref_stores; refs; refs = refs->next)
if (!strcmp(submodule, refs->name))
return refs;
return NULL;
}
/*
- * Return a pointer to a ref_cache for the specified submodule. For
+ * Return a pointer to a files_ref_store 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.
@@ -1006,16 +1006,16 @@ static struct ref_cache *lookup_ref_cache(const char *submodule)
* The returned structure will be allocated and initialized but not
* necessarily populated; it should not be freed.
*/
-static struct ref_cache *get_ref_cache(const char *submodule)
+static struct files_ref_store *get_ref_store(const char *submodule)
{
- struct ref_cache *refs = lookup_ref_cache(submodule);
+ struct files_ref_store *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 = create_ref_cache(submodule);
+ refs = create_ref_store(submodule);
strbuf_release(&submodule_sb);
}
@@ -1151,10 +1151,10 @@ static void read_packed_refs(FILE *f, struct ref_dir *dir)
}
/*
- * Get the packed_ref_cache for the specified ref_cache, creating it
- * if necessary.
+ * Get the packed_ref_cache for the specified files_ref_store,
+ * creating it if necessary.
*/
-static struct packed_ref_cache *get_packed_ref_cache(struct ref_cache *refs)
+static struct packed_ref_cache *get_packed_ref_cache(struct files_ref_store *refs)
{
char *packed_refs_file;
@@ -1189,7 +1189,7 @@ static struct ref_dir *get_packed_ref_dir(struct packed_ref_cache *packed_ref_ca
return get_ref_dir(packed_ref_cache->root);
}
-static struct ref_dir *get_packed_refs(struct ref_cache *refs)
+static struct ref_dir *get_packed_refs(struct files_ref_store *refs)
{
return get_packed_ref_dir(get_packed_ref_cache(refs));
}
@@ -1203,7 +1203,7 @@ static struct ref_dir *get_packed_refs(struct ref_cache *refs)
static void add_packed_ref(const char *refname, const unsigned char *sha1)
{
struct packed_ref_cache *packed_ref_cache =
- get_packed_ref_cache(&ref_cache);
+ get_packed_ref_cache(&ref_store);
if (!packed_ref_cache->lock)
die("internal error: packed refs not locked");
@@ -1218,7 +1218,7 @@ static void add_packed_ref(const char *refname, const unsigned char *sha1)
*/
static void read_loose_refs(const char *dirname, struct ref_dir *dir)
{
- struct ref_cache *refs = dir->ref_cache;
+ struct files_ref_store *refs = dir->ref_store;
DIR *d;
struct dirent *de;
int dirnamelen = strlen(dirname);
@@ -1306,7 +1306,7 @@ static void read_loose_refs(const char *dirname, struct ref_dir *dir)
closedir(d);
}
-static struct ref_dir *get_loose_refs(struct ref_cache *refs)
+static struct ref_dir *get_loose_refs(struct files_ref_store *refs)
{
if (!refs->loose) {
/*
@@ -1328,10 +1328,10 @@ static struct ref_dir *get_loose_refs(struct ref_cache *refs)
/*
* Called by resolve_gitlink_ref_recursive() after it failed to read
- * from the loose refs in ref_cache refs. Find <refname> in the
- * packed-refs file for the submodule.
+ * from the loose refs in refs. Find <refname> in the packed-refs file
+ * for the submodule.
*/
-static int resolve_gitlink_packed_ref(struct ref_cache *refs,
+static int resolve_gitlink_packed_ref(struct files_ref_store *refs,
const char *refname, unsigned char *sha1)
{
struct ref_entry *ref;
@@ -1345,7 +1345,7 @@ static int resolve_gitlink_packed_ref(struct ref_cache *refs,
return 0;
}
-static int resolve_gitlink_ref_recursive(struct ref_cache *refs,
+static int resolve_gitlink_ref_recursive(struct files_ref_store *refs,
const char *refname, unsigned char *sha1,
int recursion)
{
@@ -1389,7 +1389,7 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh
{
int len = strlen(path);
struct strbuf submodule = STRBUF_INIT;
- struct ref_cache *refs;
+ struct files_ref_store *refs;
while (len && path[len-1] == '/')
len--;
@@ -1397,7 +1397,7 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh
return -1;
strbuf_add(&submodule, path, len);
- refs = get_ref_cache(submodule.buf);
+ refs = get_ref_store(submodule.buf);
if (!refs) {
strbuf_release(&submodule);
return -1;
@@ -1413,7 +1413,7 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh
*/
static struct ref_entry *get_packed_ref(const char *refname)
{
- return find_ref(get_packed_refs(&ref_cache), refname);
+ return find_ref(get_packed_refs(&ref_store), refname);
}
/*
@@ -1745,7 +1745,7 @@ static int lock_raw_ref(const char *refname, int mustexist,
REMOVE_DIR_EMPTY_ONLY)) {
if (verify_refname_available_dir(
refname, extras, skip,
- get_loose_refs(&ref_cache),
+ get_loose_refs(&ref_store),
err)) {
/*
* The error message set by
@@ -1784,7 +1784,7 @@ static int lock_raw_ref(const char *refname, int mustexist,
*/
if (verify_refname_available_dir(
refname, extras, skip,
- get_packed_refs(&ref_cache),
+ get_packed_refs(&ref_store),
err)) {
goto error_return;
}
@@ -1942,7 +1942,7 @@ struct ref_iterator *files_ref_iterator_begin(
const char *submodule,
const char *prefix, unsigned int flags)
{
- struct ref_cache *refs = get_ref_cache(submodule);
+ struct files_ref_store *refs = get_ref_store(submodule);
struct ref_dir *loose_dir, *packed_dir;
struct ref_iterator *loose_iter, *packed_iter;
struct files_ref_iterator *iter;
@@ -2096,7 +2096,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
if (remove_empty_directories(&ref_file)) {
last_errno = errno;
if (!verify_refname_available_dir(refname, extras, skip,
- get_loose_refs(&ref_cache), err))
+ get_loose_refs(&ref_store), err))
strbuf_addf(err, "there are still refs under '%s'",
refname);
goto error_return;
@@ -2108,7 +2108,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
last_errno = errno;
if (last_errno != ENOTDIR ||
!verify_refname_available_dir(refname, extras, skip,
- get_loose_refs(&ref_cache), err))
+ get_loose_refs(&ref_store), err))
strbuf_addf(err, "unable to resolve reference '%s': %s",
refname, strerror(last_errno));
@@ -2123,7 +2123,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
*/
if (is_null_oid(&lock->old_oid) &&
verify_refname_available_dir(refname, extras, skip,
- get_packed_refs(&ref_cache), err)) {
+ get_packed_refs(&ref_store), err)) {
last_errno = ENOTDIR;
goto error_return;
}
@@ -2232,7 +2232,7 @@ static int lock_packed_refs(int flags)
* this will automatically invalidate the cache and re-read
* the packed-refs file.
*/
- packed_ref_cache = get_packed_ref_cache(&ref_cache);
+ packed_ref_cache = get_packed_ref_cache(&ref_store);
packed_ref_cache->lock = &packlock;
/* Increment the reference count to prevent it from being freed: */
acquire_packed_ref_cache(packed_ref_cache);
@@ -2248,7 +2248,7 @@ static int lock_packed_refs(int flags)
static int commit_packed_refs(void)
{
struct packed_ref_cache *packed_ref_cache =
- get_packed_ref_cache(&ref_cache);
+ get_packed_ref_cache(&ref_store);
int error = 0;
int save_errno = 0;
FILE *out;
@@ -2282,14 +2282,14 @@ static int commit_packed_refs(void)
static void rollback_packed_refs(void)
{
struct packed_ref_cache *packed_ref_cache =
- get_packed_ref_cache(&ref_cache);
+ get_packed_ref_cache(&ref_store);
if (!packed_ref_cache->lock)
die("internal error: packed-refs not locked");
rollback_lock_file(packed_ref_cache->lock);
packed_ref_cache->lock = NULL;
release_packed_ref_cache(packed_ref_cache);
- clear_packed_ref_cache(&ref_cache);
+ clear_packed_ref_cache(&ref_store);
}
struct ref_to_prune {
@@ -2428,9 +2428,9 @@ int pack_refs(unsigned int flags)
cbdata.flags = flags;
lock_packed_refs(LOCK_DIE_ON_ERROR);
- cbdata.packed_refs = get_packed_refs(&ref_cache);
+ cbdata.packed_refs = get_packed_refs(&ref_store);
- do_for_each_entry_in_dir(get_loose_refs(&ref_cache), 0,
+ do_for_each_entry_in_dir(get_loose_refs(&ref_store), 0,
pack_if_possible_fn, &cbdata);
if (commit_packed_refs())
@@ -2471,7 +2471,7 @@ static int repack_without_refs(struct string_list *refnames, struct strbuf *err)
unable_to_lock_message(git_path("packed-refs"), errno, err);
return -1;
}
- packed = get_packed_refs(&ref_cache);
+ packed = get_packed_refs(&ref_store);
/* Remove refnames from the cache */
for_each_string_list_item(refname, refnames)
@@ -2616,8 +2616,8 @@ int verify_refname_available(const char *newname,
const struct string_list *skip,
struct strbuf *err)
{
- struct ref_dir *packed_refs = get_packed_refs(&ref_cache);
- struct ref_dir *loose_refs = get_loose_refs(&ref_cache);
+ struct ref_dir *packed_refs = get_packed_refs(&ref_store);
+ struct ref_dir *loose_refs = get_loose_refs(&ref_store);
if (verify_refname_available_dir(newname, extras, skip,
packed_refs, err) ||
@@ -2968,7 +2968,7 @@ static int commit_ref_update(struct ref_lock *lock,
const unsigned char *sha1, const char *logmsg,
struct strbuf *err)
{
- clear_loose_ref_cache(&ref_cache);
+ clear_loose_ref_cache(&ref_store);
if (log_ref_write(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",
@@ -3800,7 +3800,7 @@ int ref_transaction_commit(struct ref_transaction *transaction,
}
}
if (update->flags & REF_NEEDS_COMMIT) {
- clear_loose_ref_cache(&ref_cache);
+ clear_loose_ref_cache(&ref_store);
if (commit_ref(lock)) {
strbuf_addf(err, "couldn't set '%s'", lock->ref_name);
unlock_ref(lock);
@@ -3833,7 +3833,7 @@ int ref_transaction_commit(struct ref_transaction *transaction,
}
for_each_string_list_item(ref_to_delete, &refs_to_delete)
unlink_or_warn(git_path("logs/%s", ref_to_delete->string));
- clear_loose_ref_cache(&ref_cache);
+ clear_loose_ref_cache(&ref_store);
cleanup:
transaction->state = REF_TRANSACTION_CLOSED;
--
2.9.3
^ permalink raw reply related
* [PATCH v2 00/38] Virtualization of the refs API
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, Michael Haggerty
This is v2 of the patch series to virtualize the references API
(though earlier patch series similar in spirit were submitted by
Ronnie Sahlberg and David Turner). Thanks to Junio, Eric, and Ramsay
for their comments about v1 [1].
Nobody pointed out any fundamental problems with v1, but this version
includes the following improvements:
* In "rename_ref_available(): add docstring":
* Improve docstring as suggested by Junio.
* In "refs: create a base class "ref_store" for files_ref_store":
* Let main_ref_store and submodule_ref_stores be initialized
implicitly rather than initializing them explicitly to NULL.
* Add docstrings for those two variables.
* Eliminate a temporary variable in `files_downcast()`.
* In "resolve_gitlink_ref(): avoid memory allocation in many cases":
* Instead of keeping track of `orig_len`, after stripping off any
trailing slashes check whether `path[len - 1]` is NUL.
* In "refs: add methods for reflog":
* Don't export `files_reflog_iterator_begin()` (suggested by
Ramsay).
In addition, given that v1 was pretty old, I have rebased the patch
series against the current upstream master. (The rebase was
unproblematic.)
This patch series is also available from my GitHub fork [2] as branch
"ref-store".
Michael
[1] http://public-inbox.org/git/cover.1464983301.git.mhagger@alum.mit.edu/t/
[2] https://github.com/mhagger/git
David Turner (8):
rename_ref_available(): add docstring
refs: add methods for reflog
refs: add method for initial ref transaction commit
refs: make delete_refs() virtual
refs: add methods to init refs db
refs: add method to rename refs
refs: make lock generic
refs: implement iteration over only per-worktree refs
Michael Haggerty (28):
resolve_gitlink_ref(): eliminate temporary variable
refs: rename struct ref_cache to files_ref_store
refs: create a base class "ref_store" for files_ref_store
add_packed_ref(): add a files_ref_store argument
get_packed_ref(): add a files_ref_store argument
resolve_missing_loose_ref(): add a files_ref_store argument
{lock,commit,rollback}_packed_refs(): add files_ref_store arguments
refs: reorder definitions
resolve_packed_ref(): rename function from resolve_missing_loose_ref()
resolve_gitlink_packed_ref(): remove function
read_raw_ref(): take a (struct ref_store *) argument
resolve_ref_recursively(): new function
resolve_gitlink_ref(): implement using resolve_ref_recursively()
resolve_gitlink_ref(): avoid memory allocation in many cases
resolve_gitlink_ref(): rename path parameter to submodule
refs: make read_raw_ref() virtual
refs: make verify_refname_available() virtual
refs: make pack_refs() virtual
refs: make create_symref() virtual
refs: make peel_ref() virtual
repack_without_refs(): add a files_ref_store argument
lock_raw_ref(): add a files_ref_store argument
commit_ref_update(): add a files_ref_store argument
lock_ref_for_update(): add a files_ref_store argument
lock_ref_sha1_basic(): add a files_ref_store argument
split_symref_update(): add a files_ref_store argument
files_ref_iterator_begin(): take a ref_store argument
refs: add method iterator_begin
Ronnie Sahlberg (2):
refs: add a backend method structure
refs: add a transaction_commit() method
builtin/init-db.c | 21 +-
refs.c | 309 +++++++++++++++++++++++++++-
refs.h | 13 +-
refs/files-backend.c | 566 +++++++++++++++++++++++++++------------------------
refs/refs-internal.h | 220 +++++++++++++++++---
5 files changed, 812 insertions(+), 317 deletions(-)
--
2.9.3
^ permalink raw reply
* [PATCH v2 16/38] resolve_gitlink_ref(): implement using resolve_ref_recursively()
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
resolve_ref_recursively() can handle references in arbitrary files
reference stores, so use it to resolve "gitlink" (i.e., submodule)
references. Aside from removing redundant code, this allows submodule
lookups to benefit from the much more robust code that we use for
reading non-submodule references. And, since the code is now agnostic
about reference backends, it will work for any future references
backend (so move its definition to refs.c).
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs.c | 24 +++++++++++++++++++
refs/files-backend.c | 67 ----------------------------------------------------
2 files changed, 24 insertions(+), 67 deletions(-)
diff --git a/refs.c b/refs.c
index 3723169..647ead5 100644
--- a/refs.c
+++ b/refs.c
@@ -1299,6 +1299,30 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
resolve_flags, sha1, flags);
}
+int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1)
+{
+ int len = strlen(path);
+ struct strbuf submodule = STRBUF_INIT;
+ struct ref_store *refs;
+ int flags;
+
+ while (len && path[len-1] == '/')
+ len--;
+ if (!len)
+ return -1;
+
+ strbuf_add(&submodule, path, len);
+ refs = get_ref_store(submodule.buf);
+ strbuf_release(&submodule);
+ if (!refs)
+ return -1;
+
+ if (!resolve_ref_recursively(refs, refname, 0, sha1, &flags) ||
+ is_null_sha1(sha1))
+ return -1;
+ return 0;
+}
+
/* A pointer to the ref_store for the main repository: */
static struct ref_store *main_ref_store;
diff --git a/refs/files-backend.c b/refs/files-backend.c
index ce6fe94..6382c6b 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1494,73 +1494,6 @@ static void unlock_ref(struct ref_lock *lock)
free(lock);
}
-#define MAXREFLEN (1024)
-
-static int resolve_gitlink_ref_recursive(struct files_ref_store *refs,
- const char *refname, unsigned char *sha1,
- int recursion)
-{
- int fd, len;
- char buffer[128], *p;
- char *path;
-
- if (recursion > SYMREF_MAXDEPTH || strlen(refname) > MAXREFLEN)
- return -1;
- path = *refs->base.submodule
- ? git_pathdup_submodule(refs->base.submodule, "%s", refname)
- : git_pathdup("%s", refname);
- fd = open(path, O_RDONLY);
- free(path);
- if (fd < 0) {
- unsigned int flags;
-
- return resolve_packed_ref(refs, refname, sha1, &flags);
- }
-
- len = read(fd, buffer, sizeof(buffer)-1);
- close(fd);
- if (len < 0)
- return -1;
- while (len && isspace(buffer[len-1]))
- len--;
- buffer[len] = 0;
-
- /* Was it a detached head or an old-fashioned symlink? */
- if (!get_sha1_hex(buffer, sha1))
- return 0;
-
- /* Symref? */
- if (strncmp(buffer, "ref:", 4))
- return -1;
- p = buffer + 4;
- while (isspace(*p))
- p++;
-
- return resolve_gitlink_ref_recursive(refs, p, sha1, recursion+1);
-}
-
-int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1)
-{
- int len = strlen(path);
- struct strbuf submodule = STRBUF_INIT;
- struct files_ref_store *refs;
-
- while (len && path[len-1] == '/')
- len--;
- if (!len)
- return -1;
-
- strbuf_add(&submodule, path, len);
- refs = get_files_ref_store(submodule.buf, "resolve_gitlink_ref");
- if (!refs) {
- strbuf_release(&submodule);
- return -1;
- }
- strbuf_release(&submodule);
-
- return resolve_gitlink_ref_recursive(refs, refname, sha1, 0);
-}
-
/*
* Lock refname, without following symrefs, and set *lock_p to point
* at a newly-allocated lock object. Fill in lock->old_oid, referent,
--
2.9.3
^ permalink raw reply related
* [PATCH v2 18/38] resolve_gitlink_ref(): rename path parameter to submodule
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs.c | 13 +++++++------
refs.h | 9 +++++----
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/refs.c b/refs.c
index 34c0c5e..e881874 100644
--- a/refs.c
+++ b/refs.c
@@ -1299,26 +1299,27 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
resolve_flags, sha1, flags);
}
-int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1)
+int resolve_gitlink_ref(const char *submodule, const char *refname,
+ unsigned char *sha1)
{
- size_t len = strlen(path);
+ size_t len = strlen(submodule);
struct ref_store *refs;
int flags;
- while (len && path[len - 1] == '/')
+ while (len && submodule[len - 1] == '/')
len--;
if (!len)
return -1;
- if (path[len]) {
+ if (submodule[len]) {
/* We need to strip off one or more trailing slashes */
- char *stripped = xmemdupz(path, len);
+ char *stripped = xmemdupz(submodule, len);
refs = get_ref_store(stripped);
free(stripped);
} else {
- refs = get_ref_store(path);
+ refs = get_ref_store(submodule);
}
if (!refs)
diff --git a/refs.h b/refs.h
index 9a29f1b..17e8cfb 100644
--- a/refs.h
+++ b/refs.h
@@ -77,11 +77,12 @@ int is_branch(const char *refname);
int peel_ref(const char *refname, unsigned char *sha1);
/**
- * Resolve refname in the nested "gitlink" repository that is located
- * at path. If the resolution is successful, return 0 and set sha1 to
- * the name of the object; otherwise, return a non-zero value.
+ * Resolve refname in the nested "gitlink" repository in the specified
+ * submodule (which must be non-NULL). If the resolution is
+ * successful, return 0 and set sha1 to the name of the object;
+ * otherwise, return a non-zero value.
*/
-int resolve_gitlink_ref(const char *path, const char *refname,
+int resolve_gitlink_ref(const char *submodule, const char *refname,
unsigned char *sha1);
/*
--
2.9.3
^ permalink raw reply related
* [PATCH v2 08/38] resolve_missing_loose_ref(): add a files_ref_store argument
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs/files-backend.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 2fc8ec9..0c92ace 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1412,13 +1412,11 @@ static struct ref_entry *get_packed_ref(struct files_ref_store *refs,
/*
* A loose ref file doesn't exist; check for a packed ref.
*/
-static int resolve_missing_loose_ref(const char *refname,
+static int resolve_missing_loose_ref(struct files_ref_store *refs,
+ const char *refname,
unsigned char *sha1,
unsigned int *flags)
{
- struct files_ref_store *refs =
- get_files_ref_store(NULL, "resolve_missing_loose_ref");
-
struct ref_entry *entry;
/*
@@ -1438,6 +1436,8 @@ static int resolve_missing_loose_ref(const char *refname,
int read_raw_ref(const char *refname, unsigned char *sha1,
struct strbuf *referent, unsigned int *type)
{
+ struct files_ref_store *refs =
+ get_files_ref_store(NULL, "read_raw_ref");
struct strbuf sb_contents = STRBUF_INIT;
struct strbuf sb_path = STRBUF_INIT;
const char *path;
@@ -1466,7 +1466,7 @@ int read_raw_ref(const char *refname, unsigned char *sha1,
if (lstat(path, &st) < 0) {
if (errno != ENOENT)
goto out;
- if (resolve_missing_loose_ref(refname, sha1, type)) {
+ if (resolve_missing_loose_ref(refs, refname, sha1, type)) {
errno = ENOENT;
goto out;
}
@@ -1500,7 +1500,7 @@ int read_raw_ref(const char *refname, unsigned char *sha1,
* ref is supposed to be, there could still be a
* packed ref:
*/
- if (resolve_missing_loose_ref(refname, sha1, type)) {
+ if (resolve_missing_loose_ref(refs, refname, sha1, type)) {
errno = EISDIR;
goto out;
}
--
2.9.3
^ permalink raw reply related
* [PATCH v2 31/38] refs: add method iterator_begin
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs.c | 2 +-
refs/files-backend.c | 3 ++-
refs/refs-internal.h | 24 ++++++++++++------------
3 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/refs.c b/refs.c
index d00126b..798b08a 100644
--- a/refs.c
+++ b/refs.c
@@ -1157,7 +1157,7 @@ static int do_for_each_ref(const char *submodule, const char *prefix,
if (!refs)
return 0;
- iter = files_ref_iterator_begin(refs, prefix, flags);
+ iter = refs->be->iterator_begin(refs, prefix, flags);
iter = prefix_ref_iterator_begin(iter, prefix, trim);
return do_for_each_ref_iterator(iter, fn, cb_data);
diff --git a/refs/files-backend.c b/refs/files-backend.c
index f521b5d..4451e13 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1862,7 +1862,7 @@ static struct ref_iterator_vtable files_ref_iterator_vtable = {
files_ref_iterator_abort
};
-struct ref_iterator *files_ref_iterator_begin(
+static struct ref_iterator *files_ref_iterator_begin(
struct ref_store *ref_store,
const char *prefix, unsigned int flags)
{
@@ -4054,6 +4054,7 @@ struct ref_storage_be refs_be_files = {
files_peel_ref,
files_create_symref,
+ files_ref_iterator_begin,
files_read_raw_ref,
files_verify_refname_available
};
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 0af1079..5be62a2 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -404,18 +404,6 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
const char *prefix,
int trim);
-struct ref_store;
-
-/*
- * Iterate over the packed and loose references in the specified
- * ref_store that are within find_containing_dir(prefix). If prefix is
- * NULL or the empty string, iterate over all references in the
- * submodule.
- */
-struct ref_iterator *files_ref_iterator_begin(struct ref_store *ref_store,
- const char *prefix,
- unsigned int flags);
-
/*
* Iterate over the references in the main ref_store that have a
* reflog. The paths within a directory are iterated over in arbitrary
@@ -488,6 +476,8 @@ int do_for_each_ref_iterator(struct ref_iterator *iter,
/* refs backends */
+struct ref_store;
+
/*
* Initialize the ref_store for the specified submodule, or for the
* main repository if submodule == NULL. These functions should call
@@ -509,6 +499,15 @@ typedef int create_symref_fn(struct ref_store *ref_store,
const char *logmsg);
/*
+ * Iterate over the references in the specified ref_store that are
+ * within find_containing_dir(prefix). If prefix is NULL or the empty
+ * string, iterate over all references in the submodule.
+ */
+typedef struct ref_iterator *ref_iterator_begin_fn(
+ struct ref_store *ref_store,
+ const char *prefix, unsigned int flags);
+
+/*
* Read a reference from the specified reference store, non-recursively.
* Set type to describe the reference, and:
*
@@ -566,6 +565,7 @@ struct ref_storage_be {
peel_ref_fn *peel_ref;
create_symref_fn *create_symref;
+ ref_iterator_begin_fn *iterator_begin;
read_raw_ref_fn *read_raw_ref;
verify_refname_available_fn *verify_refname_available;
};
--
2.9.3
^ permalink raw reply related
* [PATCH v2 35/38] refs: add methods to init refs db
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, David Turner,
Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
From: David Turner <dturner@twopensource.com>
Alternate refs backends might not need the refs/heads directory and so
on, so we make ref db initialization part of the backend.
Signed-off-by: David Turner <dturner@twopensource.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin/init-db.c | 21 +++++++++++----------
refs.c | 8 ++++++++
refs.h | 2 ++
refs/files-backend.c | 18 ++++++++++++++++++
refs/refs-internal.h | 3 +++
5 files changed, 42 insertions(+), 10 deletions(-)
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 3a45f0b..80192f6 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -180,13 +180,7 @@ static int create_default_files(const char *template_path)
char junk[2];
int reinit;
int filemode;
-
- /*
- * Create .git/refs/{heads,tags}
- */
- safe_create_dir(git_path_buf(&buf, "refs"), 1);
- safe_create_dir(git_path_buf(&buf, "refs/heads"), 1);
- safe_create_dir(git_path_buf(&buf, "refs/tags"), 1);
+ struct strbuf err = STRBUF_INIT;
/* Just look for `init.templatedir` */
git_config(git_init_db_config, NULL);
@@ -210,12 +204,19 @@ static int create_default_files(const char *template_path)
*/
if (get_shared_repository()) {
adjust_shared_perm(get_git_dir());
- adjust_shared_perm(git_path_buf(&buf, "refs"));
- adjust_shared_perm(git_path_buf(&buf, "refs/heads"));
- adjust_shared_perm(git_path_buf(&buf, "refs/tags"));
}
/*
+ * We need to create a "refs" dir in any case so that older
+ * versions of git can tell that this is a repository.
+ */
+ safe_create_dir(git_path("refs"), 1);
+ adjust_shared_perm(git_path("refs"));
+
+ if (refs_init_db(&err))
+ die("failed to set up refs db: %s", err.buf);
+
+ /*
* Create the default symlink from ".git/HEAD" to the "master"
* branch, if it does not exist yet.
*/
diff --git a/refs.c b/refs.c
index 6efa859..fcaf3ba 100644
--- a/refs.c
+++ b/refs.c
@@ -1292,6 +1292,14 @@ static const char *resolve_ref_recursively(struct ref_store *refs,
return NULL;
}
+/* backend functions */
+int refs_init_db(struct strbuf *err)
+{
+ struct ref_store *refs = get_ref_store(NULL);
+
+ return refs->be->init_db(refs, err);
+}
+
const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
unsigned char *sha1, int *flags)
{
diff --git a/refs.h b/refs.h
index 17e8cfb..d42458c 100644
--- a/refs.h
+++ b/refs.h
@@ -66,6 +66,8 @@ int ref_exists(const char *refname);
int is_branch(const char *refname);
+extern int refs_init_db(struct strbuf *err);
+
/*
* If refname is a non-symbolic reference that refers to a tag object,
* and the tag can be (recursively) dereferenced to a non-tag object,
diff --git a/refs/files-backend.c b/refs/files-backend.c
index bcaa958..56397af 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -4068,10 +4068,28 @@ static int files_reflog_expire(struct ref_store *ref_store,
return -1;
}
+static int files_init_db(struct ref_store *ref_store, struct strbuf *err)
+{
+ /* 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);
+ if (get_shared_repository()) {
+ adjust_shared_perm(git_path("refs/heads"));
+ adjust_shared_perm(git_path("refs/tags"));
+ }
+ return 0;
+}
+
struct ref_storage_be refs_be_files = {
NULL,
"files",
files_ref_store_create,
+ files_init_db,
files_transaction_commit,
files_initial_transaction_commit,
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index ade6501..b3a2095 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -479,6 +479,8 @@ struct ref_store;
*/
typedef struct ref_store *ref_store_init_fn(const char *submodule);
+typedef int ref_init_db_fn(struct ref_store *refs, struct strbuf *err);
+
typedef int ref_transaction_commit_fn(struct ref_store *refs,
struct ref_transaction *transaction,
struct strbuf *err);
@@ -583,6 +585,7 @@ struct ref_storage_be {
struct ref_storage_be *next;
const char *name;
ref_store_init_fn *init;
+ ref_init_db_fn *init_db;
ref_transaction_commit_fn *transaction_commit;
ref_transaction_commit_fn *initial_transaction_commit;
--
2.9.3
^ permalink raw reply related
* [PATCH v2 38/38] refs: implement iteration over only per-worktree refs
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, David Turner,
Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
From: David Turner <dturner@twopensource.com>
Alternate refs backends might still use files to store per-worktree
refs. So provide a way to iterate over only the per-worktree references
in a ref_store. The other backend can set up a files ref_store and
iterate using the new DO_FOR_EACH_PER_WORKTREE_ONLY flag when iterating.
Signed-off-by: David Turner <dturner@twopensource.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs/files-backend.c | 4 ++++
refs/refs-internal.h | 10 +++++++++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 0714c3f..2644792 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1798,6 +1798,10 @@ static int files_ref_iterator_advance(struct ref_iterator *ref_iterator)
int ok;
while ((ok = ref_iterator_advance(iter->iter0)) == ITER_OK) {
+ if (iter->flags & DO_FOR_EACH_PER_WORKTREE_ONLY &&
+ ref_type(iter->iter0->refname) != REF_TYPE_PER_WORKTREE)
+ continue;
+
if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) &&
!ref_resolves_to_object(iter->iter0->refname,
iter->iter0->oid,
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 681982b..708b260 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -467,10 +467,18 @@ extern struct ref_iterator *current_ref_iter;
int do_for_each_ref_iterator(struct ref_iterator *iter,
each_ref_fn fn, void *cb_data);
-/* refs backends */
+/*
+ * Only include per-worktree refs in a do_for_each_ref*() iteration.
+ * Normally this will be used with a files ref_store, since that's
+ * where all reference backends will presumably store their
+ * per-worktree refs.
+ */
+#define DO_FOR_EACH_PER_WORKTREE_ONLY 0x02
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
--
2.9.3
^ permalink raw reply related
* [PATCH v2 32/38] refs: add methods for reflog
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, David Turner,
Ronnie Sahlberg, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
From: David Turner <dturner@twopensource.com>
In the file-based backend, the reflog piggybacks on the ref lock.
Since other backends won't have the same sort of ref lock, ref backends
must also handle reflogs.
Signed-off-by: Ronnie Sahlberg <rsahlberg@google.com>
Signed-off-by: David Turner <dturner@twopensource.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++
refs/files-backend.c | 70 +++++++++++++++++++++++++++++++++++++---------------
refs/refs-internal.h | 44 +++++++++++++++++++++++++++------
3 files changed, 150 insertions(+), 27 deletions(-)
diff --git a/refs.c b/refs.c
index 798b08a..cb9d805 100644
--- a/refs.c
+++ b/refs.c
@@ -1461,3 +1461,66 @@ int verify_refname_available(const char *refname,
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_iterator *iter;
+
+ iter = refs->be->reflog_iterator_begin(refs);
+
+ return do_for_each_ref_iterator(iter, fn, 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);
+
+ return refs->be->for_each_reflog_ent_reverse(refs, refname,
+ fn, cb_data);
+}
+
+int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn,
+ void *cb_data)
+{
+ struct ref_store *refs = get_ref_store(NULL);
+
+ 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);
+
+ return refs->be->reflog_exists(refs, refname);
+}
+
+int safe_create_reflog(const char *refname, int force_create,
+ struct strbuf *err)
+{
+ struct ref_store *refs = get_ref_store(NULL);
+
+ return refs->be->create_reflog(refs, refname, force_create, err);
+}
+
+int delete_reflog(const char *refname)
+{
+ struct ref_store *refs = get_ref_store(NULL);
+
+ return refs->be->delete_reflog(refs, refname);
+}
+
+int reflog_expire(const char *refname, const unsigned char *sha1,
+ unsigned int flags,
+ reflog_expiry_prepare_fn prepare_fn,
+ reflog_expiry_should_prune_fn should_prune_fn,
+ reflog_expiry_cleanup_fn cleanup_fn,
+ void *policy_cb_data)
+{
+ struct ref_store *refs = get_ref_store(NULL);
+
+ return refs->be->reflog_expire(refs, refname, sha1, flags,
+ prepare_fn, should_prune_fn,
+ cleanup_fn, policy_cb_data);
+}
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 4451e13..a810dfa 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -2777,11 +2777,16 @@ static int log_ref_setup(const char *refname, struct strbuf *logfile, struct str
}
-int safe_create_reflog(const char *refname, int force_create, struct strbuf *err)
+static int files_create_reflog(struct ref_store *ref_store,
+ const char *refname, int force_create,
+ struct strbuf *err)
{
int ret;
struct strbuf sb = STRBUF_INIT;
+ /* 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);
strbuf_release(&sb);
return ret;
@@ -3075,16 +3080,24 @@ int set_worktree_head_symref(const char *gitdir, const char *target)
return ret;
}
-int reflog_exists(const char *refname)
+static int files_reflog_exists(struct ref_store *ref_store,
+ const char *refname)
{
struct stat st;
+ /* 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);
}
-int delete_reflog(const char *refname)
+static int files_delete_reflog(struct ref_store *ref_store,
+ const char *refname)
{
+ /* Check validity (but we don't need the result): */
+ files_downcast(ref_store, 0, "delete_reflog");
+
return remove_path(git_path("logs/%s", refname));
}
@@ -3127,13 +3140,19 @@ static char *find_beginning_of_line(char *bob, char *scan)
return scan;
}
-int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void *cb_data)
+static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store,
+ const char *refname,
+ each_reflog_ent_fn fn,
+ void *cb_data)
{
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");
+
logfp = fopen(git_path("logs/%s", refname), "r");
if (!logfp)
return -1;
@@ -3229,12 +3248,17 @@ int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void
return ret;
}
-int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_data)
+static int files_for_each_reflog_ent(struct ref_store *ref_store,
+ const char *refname,
+ each_reflog_ent_fn fn, void *cb_data)
{
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");
+
logfp = fopen(git_path("logs/%s", refname), "r");
if (!logfp)
return -1;
@@ -3313,22 +3337,19 @@ static struct ref_iterator_vtable files_reflog_iterator_vtable = {
files_reflog_iterator_abort
};
-struct ref_iterator *files_reflog_iterator_begin(void)
+static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_store)
{
struct files_reflog_iterator *iter = xcalloc(1, sizeof(*iter));
struct ref_iterator *ref_iterator = &iter->base;
+ /* 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"));
return ref_iterator;
}
-int for_each_reflog(each_ref_fn fn, void *cb_data)
-{
- return do_for_each_ref_iterator(files_reflog_iterator_begin(),
- fn, cb_data);
-}
-
static int ref_update_reject_duplicates(struct string_list *refnames,
struct strbuf *err)
{
@@ -3935,15 +3956,16 @@ static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
return 0;
}
-int reflog_expire(const char *refname, const unsigned char *sha1,
- unsigned int flags,
- reflog_expiry_prepare_fn prepare_fn,
- reflog_expiry_should_prune_fn should_prune_fn,
- reflog_expiry_cleanup_fn cleanup_fn,
- void *policy_cb_data)
+static int files_reflog_expire(struct ref_store *ref_store,
+ const char *refname, const unsigned char *sha1,
+ unsigned int flags,
+ reflog_expiry_prepare_fn prepare_fn,
+ reflog_expiry_should_prune_fn should_prune_fn,
+ reflog_expiry_cleanup_fn cleanup_fn,
+ void *policy_cb_data)
{
struct files_ref_store *refs =
- get_files_ref_store(NULL, "reflog_expire");
+ files_downcast(ref_store, 0, "reflog_expire");
static struct lock_file reflog_lock;
struct expire_reflog_cb cb;
struct ref_lock *lock;
@@ -4056,5 +4078,13 @@ struct ref_storage_be refs_be_files = {
files_ref_iterator_begin,
files_read_raw_ref,
- files_verify_refname_available
+ files_verify_refname_available,
+
+ files_reflog_iterator_begin,
+ files_for_each_reflog_ent,
+ files_for_each_reflog_ent_reverse,
+ files_reflog_exists,
+ files_create_reflog,
+ files_delete_reflog,
+ files_reflog_expire
};
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 5be62a2..a20b622 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -404,13 +404,6 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
const char *prefix,
int trim);
-/*
- * Iterate over the references in the main ref_store that have a
- * reflog. The paths within a directory are iterated over in arbitrary
- * order.
- */
-struct ref_iterator *files_reflog_iterator_begin(void);
-
/* Internal implementation of reference iteration: */
/*
@@ -507,6 +500,35 @@ typedef struct ref_iterator *ref_iterator_begin_fn(
struct ref_store *ref_store,
const char *prefix, unsigned int flags);
+/* reflog functions */
+
+/*
+ * Iterate over the references in the specified ref_store that have a
+ * reflog. The refs are iterated over in arbitrary order.
+ */
+typedef struct ref_iterator *reflog_iterator_begin_fn(
+ struct ref_store *ref_store);
+
+typedef int for_each_reflog_ent_fn(struct ref_store *ref_store,
+ const char *refname,
+ each_reflog_ent_fn fn,
+ void *cb_data);
+typedef int for_each_reflog_ent_reverse_fn(struct ref_store *ref_store,
+ const char *refname,
+ each_reflog_ent_fn fn,
+ void *cb_data);
+typedef int reflog_exists_fn(struct ref_store *ref_store, const char *refname);
+typedef int create_reflog_fn(struct ref_store *ref_store, const char *refname,
+ int force_create, struct strbuf *err);
+typedef int delete_reflog_fn(struct ref_store *ref_store, const char *refname);
+typedef int reflog_expire_fn(struct ref_store *ref_store,
+ const char *refname, const unsigned char *sha1,
+ unsigned int flags,
+ reflog_expiry_prepare_fn prepare_fn,
+ reflog_expiry_should_prune_fn should_prune_fn,
+ reflog_expiry_cleanup_fn cleanup_fn,
+ void *policy_cb_data);
+
/*
* Read a reference from the specified reference store, non-recursively.
* Set type to describe the reference, and:
@@ -568,6 +590,14 @@ struct ref_storage_be {
ref_iterator_begin_fn *iterator_begin;
read_raw_ref_fn *read_raw_ref;
verify_refname_available_fn *verify_refname_available;
+
+ reflog_iterator_begin_fn *reflog_iterator_begin;
+ for_each_reflog_ent_fn *for_each_reflog_ent;
+ for_each_reflog_ent_reverse_fn *for_each_reflog_ent_reverse;
+ reflog_exists_fn *reflog_exists;
+ create_reflog_fn *create_reflog;
+ delete_reflog_fn *delete_reflog;
+ reflog_expire_fn *reflog_expire;
};
extern struct ref_storage_be refs_be_files;
--
2.9.3
^ permalink raw reply related
* [PATCH v2 33/38] refs: add method for initial ref transaction commit
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, David Turner,
Ronnie Sahlberg, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
From: David Turner <dturner@twopensource.com>
Signed-off-by: Ronnie Sahlberg <rsahlberg@google.com>
Signed-off-by: David Turner <dturner@twopensource.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs.c | 8 ++++++++
refs/files-backend.c | 8 +++++---
refs/refs-internal.h | 1 +
3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/refs.c b/refs.c
index cb9d805..3830918 100644
--- a/refs.c
+++ b/refs.c
@@ -1524,3 +1524,11 @@ int reflog_expire(const char *refname, const unsigned char *sha1,
prepare_fn, should_prune_fn,
cleanup_fn, policy_cb_data);
}
+
+int initial_ref_transaction_commit(struct ref_transaction *transaction,
+ struct strbuf *err)
+{
+ struct ref_store *refs = get_ref_store(NULL);
+
+ return refs->be->initial_transaction_commit(refs, transaction, err);
+}
diff --git a/refs/files-backend.c b/refs/files-backend.c
index a810dfa..81008d7 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -3839,11 +3839,12 @@ static int ref_present(const char *refname,
return string_list_has_string(affected_refnames, refname);
}
-int initial_ref_transaction_commit(struct ref_transaction *transaction,
- struct strbuf *err)
+static int files_initial_transaction_commit(struct ref_store *ref_store,
+ struct ref_transaction *transaction,
+ struct strbuf *err)
{
struct files_ref_store *refs =
- get_files_ref_store(NULL, "initial_ref_transaction_commit");
+ files_downcast(ref_store, 0, "initial_ref_transaction_commit");
int ret = 0, i;
struct string_list affected_refnames = STRING_LIST_INIT_NODUP;
@@ -4071,6 +4072,7 @@ struct ref_storage_be refs_be_files = {
"files",
files_ref_store_create,
files_transaction_commit,
+ files_initial_transaction_commit,
files_pack_refs,
files_peel_ref,
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index a20b622..08c8586 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -582,6 +582,7 @@ struct ref_storage_be {
const char *name;
ref_store_init_fn *init;
ref_transaction_commit_fn *transaction_commit;
+ ref_transaction_commit_fn *initial_transaction_commit;
pack_refs_fn *pack_refs;
peel_ref_fn *peel_ref;
--
2.9.3
^ permalink raw reply related
* [PATCH v2 29/38] split_symref_update(): add a files_ref_store argument
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs/files-backend.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index ab2c1de..3a0db5a 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -3401,7 +3401,8 @@ static int split_head_update(struct ref_update *update,
* Note that the new update will itself be subject to splitting when
* the iteration gets to it.
*/
-static int split_symref_update(struct ref_update *update,
+static int split_symref_update(struct files_ref_store *refs,
+ struct ref_update *update,
const char *referent,
struct ref_transaction *transaction,
struct string_list *affected_refnames,
@@ -3583,7 +3584,8 @@ static int lock_ref_for_update(struct files_ref_store *refs,
* of processing the split-off update, so we
* don't have to do it here.
*/
- ret = split_symref_update(update, referent.buf, transaction,
+ ret = split_symref_update(refs, update,
+ referent.buf, transaction,
affected_refnames, err);
if (ret)
return ret;
--
2.9.3
^ permalink raw reply related
* [PATCH v2 37/38] refs: make lock generic
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, David Turner,
Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
From: David Turner <dturner@twopensource.com>
Instead of including a files-backend-specific struct ref_lock, change
the generic ref_update struct to include a void pointer that backends
can use for their own arbitrary data.
Signed-off-by: David Turner <dturner@twopensource.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs/files-backend.c | 25 +++++++++++++------------
refs/refs-internal.h | 2 +-
2 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 7cc4191..0714c3f 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -3552,9 +3552,8 @@ static int lock_ref_for_update(struct files_ref_store *refs,
ret = lock_raw_ref(refs, update->refname, mustexist,
affected_refnames, NULL,
- &update->lock, &referent,
+ &lock, &referent,
&update->type, err);
-
if (ret) {
char *reason;
@@ -3565,7 +3564,7 @@ static int lock_ref_for_update(struct files_ref_store *refs,
return ret;
}
- lock = update->lock;
+ update->backend_data = lock;
if (update->type & REF_ISSYMREF) {
if (update->flags & REF_NODEREF) {
@@ -3613,7 +3612,8 @@ static int lock_ref_for_update(struct files_ref_store *refs,
for (parent_update = update->parent_update;
parent_update;
parent_update = parent_update->parent_update) {
- oidcpy(&parent_update->lock->old_oid, &lock->old_oid);
+ struct ref_lock *parent_lock = parent_update->backend_data;
+ oidcpy(&parent_lock->old_oid, &lock->old_oid);
}
}
@@ -3634,7 +3634,7 @@ static int lock_ref_for_update(struct files_ref_store *refs,
* The lock was freed upon failure of
* write_ref_to_lockfile():
*/
- update->lock = NULL;
+ update->backend_data = NULL;
strbuf_addf(err,
"cannot update ref '%s': %s",
update->refname, write_err);
@@ -3752,7 +3752,7 @@ static int files_transaction_commit(struct ref_store *ref_store,
/* Perform updates first so live commits remain referenced */
for (i = 0; i < transaction->nr; i++) {
struct ref_update *update = transaction->updates[i];
- struct ref_lock *lock = update->lock;
+ struct ref_lock *lock = update->backend_data;
if (update->flags & REF_NEEDS_COMMIT ||
update->flags & REF_LOG_ONLY) {
@@ -3765,7 +3765,7 @@ static int files_transaction_commit(struct ref_store *ref_store,
lock->ref_name, old_msg);
free(old_msg);
unlock_ref(lock);
- update->lock = NULL;
+ update->backend_data = NULL;
ret = TRANSACTION_GENERIC_ERROR;
goto cleanup;
}
@@ -3775,7 +3775,7 @@ static int files_transaction_commit(struct ref_store *ref_store,
if (commit_ref(lock)) {
strbuf_addf(err, "couldn't set '%s'", lock->ref_name);
unlock_ref(lock);
- update->lock = NULL;
+ update->backend_data = NULL;
ret = TRANSACTION_GENERIC_ERROR;
goto cleanup;
}
@@ -3784,17 +3784,18 @@ static int files_transaction_commit(struct ref_store *ref_store,
/* Perform deletes now that updates are safely completed */
for (i = 0; i < transaction->nr; i++) {
struct ref_update *update = transaction->updates[i];
+ struct ref_lock *lock = update->backend_data;
if (update->flags & REF_DELETING &&
!(update->flags & REF_LOG_ONLY)) {
- if (delete_ref_loose(update->lock, update->type, err)) {
+ if (delete_ref_loose(lock, update->type, err)) {
ret = TRANSACTION_GENERIC_ERROR;
goto cleanup;
}
if (!(update->flags & REF_ISPRUNING))
string_list_append(&refs_to_delete,
- update->lock->ref_name);
+ lock->ref_name);
}
}
@@ -3810,8 +3811,8 @@ static int files_transaction_commit(struct ref_store *ref_store,
transaction->state = REF_TRANSACTION_CLOSED;
for (i = 0; i < transaction->nr; i++)
- if (transaction->updates[i]->lock)
- unlock_ref(transaction->updates[i]->lock);
+ if (transaction->updates[i]->backend_data)
+ unlock_ref(transaction->updates[i]->backend_data);
string_list_clear(&refs_to_delete, 0);
free(head_ref);
string_list_clear(&affected_refnames, 0);
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index c598cb1..681982b 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -162,7 +162,7 @@ struct ref_update {
*/
unsigned int flags;
- struct ref_lock *lock;
+ void *backend_data;
unsigned int type;
char *msg;
--
2.9.3
^ permalink raw reply related
* [PATCH v2 30/38] files_ref_iterator_begin(): take a ref_store argument
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs.c | 2 +-
refs/files-backend.c | 4 ++--
refs/refs-internal.h | 8 ++++----
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/refs.c b/refs.c
index f10f86a..d00126b 100644
--- a/refs.c
+++ b/refs.c
@@ -1157,7 +1157,7 @@ static int do_for_each_ref(const char *submodule, const char *prefix,
if (!refs)
return 0;
- iter = files_ref_iterator_begin(submodule, prefix, flags);
+ iter = files_ref_iterator_begin(refs, prefix, flags);
iter = prefix_ref_iterator_begin(iter, prefix, trim);
return do_for_each_ref_iterator(iter, fn, cb_data);
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 3a0db5a..f521b5d 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1863,11 +1863,11 @@ static struct ref_iterator_vtable files_ref_iterator_vtable = {
};
struct ref_iterator *files_ref_iterator_begin(
- const char *submodule,
+ struct ref_store *ref_store,
const char *prefix, unsigned int flags)
{
struct files_ref_store *refs =
- get_files_ref_store(submodule, "ref_iterator_begin");
+ files_downcast(ref_store, 1, "ref_iterator_begin");
struct ref_dir *loose_dir, *packed_dir;
struct ref_iterator *loose_iter, *packed_iter;
struct files_ref_iterator *iter;
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 84c81ad..0af1079 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -404,13 +404,15 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
const char *prefix,
int trim);
+struct ref_store;
+
/*
* Iterate over the packed and loose references in the specified
- * submodule that are within find_containing_dir(prefix). If prefix is
+ * ref_store that are within find_containing_dir(prefix). If prefix is
* NULL or the empty string, iterate over all references in the
* submodule.
*/
-struct ref_iterator *files_ref_iterator_begin(const char *submodule,
+struct ref_iterator *files_ref_iterator_begin(struct ref_store *ref_store,
const char *prefix,
unsigned int flags);
@@ -484,8 +486,6 @@ extern struct ref_iterator *current_ref_iter;
int do_for_each_ref_iterator(struct ref_iterator *iter,
each_ref_fn fn, void *cb_data);
-struct ref_store;
-
/* refs backends */
/*
--
2.9.3
^ permalink raw reply related
* [PATCH v2 22/38] refs: make create_symref() virtual
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs.c | 9 +++++++++
refs/files-backend.c | 7 ++++++-
refs/refs-internal.h | 5 +++++
3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/refs.c b/refs.c
index 961927a..74874e5 100644
--- a/refs.c
+++ b/refs.c
@@ -1428,6 +1428,15 @@ int pack_refs(unsigned int flags)
return refs->be->pack_refs(refs, flags);
}
+int create_symref(const char *ref_target, const char *refs_heads_master,
+ const char *logmsg)
+{
+ struct ref_store *refs = get_ref_store(NULL);
+
+ return refs->be->create_symref(refs, ref_target, refs_heads_master,
+ logmsg);
+}
+
int ref_transaction_commit(struct ref_transaction *transaction,
struct strbuf *err)
{
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 7ad8821..bf53670 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -3011,12 +3011,16 @@ static int create_symref_locked(struct ref_lock *lock, const char *refname,
return 0;
}
-int create_symref(const char *refname, const char *target, const char *logmsg)
+static int files_create_symref(struct ref_store *ref_store,
+ const char *refname, const char *target,
+ const char *logmsg)
{
struct strbuf err = STRBUF_INIT;
struct ref_lock *lock;
int ret;
+ files_downcast(ref_store, 0, "create_symref");
+
lock = lock_ref_sha1_basic(refname, NULL, NULL, NULL, REF_NODEREF, NULL,
&err);
if (!lock) {
@@ -4033,6 +4037,7 @@ struct ref_storage_be refs_be_files = {
files_transaction_commit,
files_pack_refs,
+ files_create_symref,
files_read_raw_ref,
files_verify_refname_available
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 256f7f5..bf96503 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -501,6 +501,10 @@ typedef int ref_transaction_commit_fn(struct ref_store *refs,
struct strbuf *err);
typedef int pack_refs_fn(struct ref_store *ref_store, unsigned int flags);
+typedef int create_symref_fn(struct ref_store *ref_store,
+ const char *ref_target,
+ const char *refs_heads_master,
+ const char *logmsg);
/*
* Read a reference from the specified reference store, non-recursively.
@@ -557,6 +561,7 @@ struct ref_storage_be {
ref_transaction_commit_fn *transaction_commit;
pack_refs_fn *pack_refs;
+ create_symref_fn *create_symref;
read_raw_ref_fn *read_raw_ref;
verify_refname_available_fn *verify_refname_available;
--
2.9.3
^ permalink raw reply related
* [PATCH v2 27/38] lock_ref_for_update(): add a files_ref_store argument
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs/files-backend.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 001b8ef..2f8eb54 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -3514,20 +3514,21 @@ static int check_old_oid(struct ref_update *update, struct object_id *oid,
* - If it is an update of head_ref, add a corresponding REF_LOG_ONLY
* update of HEAD.
*/
-static int lock_ref_for_update(struct ref_update *update,
+static int lock_ref_for_update(struct files_ref_store *refs,
+ struct ref_update *update,
struct ref_transaction *transaction,
const char *head_ref,
struct string_list *affected_refnames,
struct strbuf *err)
{
- struct files_ref_store *refs =
- get_files_ref_store(NULL, "lock_ref_for_update");
struct strbuf referent = STRBUF_INIT;
int mustexist = (update->flags & REF_HAVE_OLD) &&
!is_null_sha1(update->old_sha1);
int ret;
struct ref_lock *lock;
+ assert_main_repository(&refs->base, "lock_ref_for_update");
+
if ((update->flags & REF_HAVE_NEW) && is_null_sha1(update->new_sha1))
update->flags |= REF_DELETING;
@@ -3730,8 +3731,8 @@ static int files_transaction_commit(struct ref_store *ref_store,
for (i = 0; i < transaction->nr; i++) {
struct ref_update *update = transaction->updates[i];
- ret = lock_ref_for_update(update, transaction, head_ref,
- &affected_refnames, err);
+ ret = lock_ref_for_update(refs, update, transaction,
+ head_ref, &affected_refnames, err);
if (ret)
goto cleanup;
}
--
2.9.3
^ permalink raw reply related
* [PATCH v2 26/38] commit_ref_update(): add a files_ref_store argument
From: Michael Haggerty @ 2016-09-04 16:08 UTC (permalink / raw)
To: Junio C Hamano
Cc: David Turner, Ramsay Jones, Eric Sunshine, Jeff King,
Nguyễn Thái Ngọc Duy, git, Michael Haggerty
In-Reply-To: <cover.1473003902.git.mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
refs/files-backend.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index ae425c5..001b8ef 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -2574,12 +2574,14 @@ static int files_verify_refname_available(struct ref_store *ref_store,
static int write_ref_to_lockfile(struct ref_lock *lock,
const unsigned char *sha1, struct strbuf *err);
-static int commit_ref_update(struct ref_lock *lock,
+static int commit_ref_update(struct files_ref_store *refs,
+ struct ref_lock *lock,
const unsigned char *sha1, const char *logmsg,
struct strbuf *err);
int rename_ref(const char *oldrefname, const char *newrefname, const char *logmsg)
{
+ struct files_ref_store *refs = get_files_ref_store(NULL, "rename_ref");
unsigned char sha1[20], orig_sha1[20];
int flag = 0, logmoved = 0;
struct ref_lock *lock;
@@ -2652,7 +2654,7 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
hashcpy(lock->old_oid.hash, orig_sha1);
if (write_ref_to_lockfile(lock, orig_sha1, &err) ||
- commit_ref_update(lock, orig_sha1, logmsg, &err)) {
+ commit_ref_update(refs, lock, orig_sha1, logmsg, &err)) {
error("unable to write current sha1 into %s: %s", newrefname, err.buf);
strbuf_release(&err);
goto rollback;
@@ -2672,7 +2674,7 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
flag = log_all_ref_updates;
log_all_ref_updates = 0;
if (write_ref_to_lockfile(lock, orig_sha1, &err) ||
- commit_ref_update(lock, orig_sha1, NULL, &err)) {
+ commit_ref_update(refs, lock, orig_sha1, NULL, &err)) {
error("unable to write current sha1 into %s: %s", oldrefname, err.buf);
strbuf_release(&err);
}
@@ -2908,12 +2910,12 @@ static int write_ref_to_lockfile(struct ref_lock *lock,
* to the loose reference lockfile. Also update the reflogs if
* necessary, using the specified lockmsg (which can be NULL).
*/
-static int commit_ref_update(struct ref_lock *lock,
+static int commit_ref_update(struct files_ref_store *refs,
+ struct ref_lock *lock,
const unsigned char *sha1, const char *logmsg,
struct strbuf *err)
{
- struct files_ref_store *refs =
- get_files_ref_store(NULL, "commit_ref_update");
+ assert_main_repository(&refs->base, "commit_ref_update");
clear_loose_ref_cache(refs);
if (log_ref_write(lock->ref_name, lock->old_oid.hash, sha1, logmsg, 0, err)) {
--
2.9.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox