From: David Turner <dturner@twopensource.com>
To: git@vger.kernel.org, mhagger@alum.mit.edu
Cc: David Turner <dturner@twopensource.com>
Subject: [PATCH v7 7/8] update-ref and tag: add --create-reflog arg
Date: Tue, 7 Jul 2015 20:56:02 -0400 [thread overview]
Message-ID: <1436316963-25520-7-git-send-email-dturner@twopensource.com> (raw)
In-Reply-To: <1436316963-25520-1-git-send-email-dturner@twopensource.com>
Allow the creation of a ref (e.g. stash) with a reflog already in
place. For most refs (e.g. those under refs/heads), this happens
automatically, but for others, we need this option.
Currently, git does this by pre-creating the reflog, but alternate ref
backends might store reflogs somewhere other than .git/logs. Code
that now directly manipulates .git/logs should instead use git
plumbing commands.
I also added --create-reflog to git tag, just for completeness.
In a moment, we will use this argument to make git stash work with
alternate ref backends.
Signed-off-by: David Turner <dturner@twopensource.com>
---
Documentation/git-tag.txt | 5 ++++-
Documentation/git-update-ref.txt | 5 ++++-
builtin/tag.c | 5 +++++
builtin/update-ref.c | 17 +++++++++++++++--
t/t1400-update-ref.sh | 38 ++++++++++++++++++++++++++++++++++++++
t/t7004-tag.sh | 9 ++++++++-
6 files changed, 74 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index 034d10d..2312980 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -13,7 +13,7 @@ SYNOPSIS
<tagname> [<commit> | <object>]
'git tag' -d <tagname>...
'git tag' [-n[<num>]] -l [--contains <commit>] [--points-at <object>]
- [--column[=<options>] | --no-column] [<pattern>...]
+ [--column[=<options>] | --no-column] [--create-reflog] [<pattern>...]
[<pattern>...]
'git tag' -v <tagname>...
@@ -143,6 +143,9 @@ This option is only applicable when listing tags without annotation lines.
all, 'whitespace' removes just leading/trailing whitespace lines and
'strip' removes both whitespace and commentary.
+--create-reflog::
+ Create a reflog for the tag.
+
<tagname>::
The name of the tag to create, delete, or describe.
The new tag name must pass all checks defined by
diff --git a/Documentation/git-update-ref.txt b/Documentation/git-update-ref.txt
index c8f5ae5..969bfab 100644
--- a/Documentation/git-update-ref.txt
+++ b/Documentation/git-update-ref.txt
@@ -8,7 +8,7 @@ git-update-ref - Update the object name stored in a ref safely
SYNOPSIS
--------
[verse]
-'git update-ref' [-m <reason>] (-d <ref> [<oldvalue>] | [--no-deref] <ref> <newvalue> [<oldvalue>] | --stdin [-z])
+'git update-ref' [-m <reason>] (-d <ref> [<oldvalue>] | [--no-deref] [--create-reflog] <ref> <newvalue> [<oldvalue>] | --stdin [-z])
DESCRIPTION
-----------
@@ -67,6 +67,9 @@ performs all modifications together. Specify commands of the form:
verify SP <ref> [SP <oldvalue>] LF
option SP <opt> LF
+With `--create-reflog`, update-ref will create a reflog for each ref
+even if one would not ordinarily be created.
+
Quote fields containing whitespace as if they were strings in C source
code; i.e., surrounded by double-quotes and with backslash escapes.
Use 40 "0" characters or the empty string to specify a zero value. To
diff --git a/builtin/tag.c b/builtin/tag.c
index 5f6cdc5..896f434 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -579,6 +579,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
struct create_tag_options opt;
char *cleanup_arg = NULL;
int annotate = 0, force = 0, lines = -1;
+ int create_reflog = 0;
int cmdmode = 0;
const char *msgfile = NULL, *keyid = NULL;
struct msg_arg msg = { 0, STRBUF_INIT };
@@ -605,6 +606,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
OPT_STRING('u', "local-user", &keyid, N_("key-id"),
N_("use another key to sign the tag")),
OPT__FORCE(&force, N_("replace the tag if exists")),
+ OPT_BOOL(0, "create-reflog", &create_reflog, N_("create_reflog")),
OPT_GROUP(N_("Tag listing options")),
OPT_COLUMN(0, "column", &colopts, N_("show tag list in columns")),
@@ -730,6 +732,9 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
if (annotate)
create_tag(object, tag, &buf, &opt, prev, object);
+ if (create_reflog && safe_create_reflog(ref.buf, &err, 1))
+ die("failed to create reflog for %s: %s", ref.buf, err.buf);
+
transaction = ref_transaction_begin(&err);
if (!transaction ||
ref_transaction_update(transaction, ref.buf, object, prev,
diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 6763cf1..d570e5e 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -14,6 +14,7 @@ static const char * const git_update_ref_usage[] = {
static char line_termination = '\n';
static int update_flags;
+int create_reflog;
static const char *msg;
/*
@@ -198,6 +199,9 @@ static const char *parse_cmd_update(struct ref_transaction *transaction,
if (*next != line_termination)
die("update %s: extra input: %s", refname, next);
+ if (create_reflog && safe_create_reflog(refname, &err, 1))
+ die("failed to create reflog for %s: %s", refname, err.buf);
+
if (ref_transaction_update(transaction, refname,
new_sha1, have_old ? old_sha1 : NULL,
update_flags, msg, &err))
@@ -230,6 +234,9 @@ static const char *parse_cmd_create(struct ref_transaction *transaction,
if (*next != line_termination)
die("create %s: extra input: %s", refname, next);
+ if (create_reflog && safe_create_reflog(refname, &err, 1))
+ die("failed to create reflog for %s: %s", refname, err.buf);
+
if (ref_transaction_create(transaction, refname, new_sha1,
update_flags, msg, &err))
die("%s", err.buf);
@@ -361,6 +368,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
N_("update <refname> not the one it points to")),
OPT_BOOL('z', NULL, &end_null, N_("stdin has NUL-terminated arguments")),
OPT_BOOL( 0 , "stdin", &read_stdin, N_("read updates from stdin")),
+ OPT_BOOL( 0 , "create-reflog", &create_reflog, N_("create_reflog")),
OPT_END(),
};
@@ -421,7 +429,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
if (no_deref)
flags = REF_NODEREF;
- if (delete)
+ if (delete) {
/*
* For purposes of backwards compatibility, we treat
* NULL_SHA1 as "don't care" here:
@@ -429,7 +437,12 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
return delete_ref(refname,
(oldval && !is_null_sha1(oldsha1)) ? oldsha1 : NULL,
flags);
- else
+ } else {
+ struct strbuf err = STRBUF_INIT;
+ if (create_reflog && safe_create_reflog(refname, &err, 1))
+ die("failed to create reflog for %s: %s", refname, err.buf);
+
return update_ref(msg, refname, sha1, oldval ? oldsha1 : NULL,
flags, UPDATE_REFS_DIE_ON_ERR);
+ }
}
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index d787bf5..9d21c19 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -23,6 +23,7 @@ test_expect_success setup '
m=refs/heads/master
n_dir=refs/heads/gu
n=$n_dir/fixes
+outside=foo
test_expect_success \
"create $m" \
@@ -74,6 +75,24 @@ test_expect_success "delete $m (by HEAD)" '
'
rm -f .git/$m
+test_expect_success 'update-ref does not create reflogs by default' '
+ test_when_finished "git update-ref -d $outside" &&
+ git update-ref $outside $A &&
+ git rev-parse $A >expect &&
+ git rev-parse $outside >actual &&
+ test_cmp expect actual &&
+ test_must_fail git reflog exists $outside
+'
+
+test_expect_success 'update-ref creates reflogs with --create-reflog' '
+ test_when_finished "git update-ref -d $outside" &&
+ git update-ref --create-reflog $outside $A &&
+ git rev-parse $A >expect &&
+ git rev-parse $outside >actual &&
+ test_cmp expect actual &&
+ git reflog exists $outside
+'
+
test_expect_success \
"create $m (by HEAD)" \
"git update-ref HEAD $A &&
@@ -472,6 +491,25 @@ test_expect_success 'stdin create ref works' '
test_cmp expect actual
'
+test_expect_success 'stdin does not create reflogs by default' '
+ test_when_finished "git update-ref -d $outside" &&
+ echo "create $outside $m" >stdin &&
+ git update-ref --stdin <stdin &&
+ git rev-parse $m >expect &&
+ git rev-parse $outside >actual &&
+ test_cmp expect actual &&
+ test_must_fail git reflog exists $outside
+'
+
+test_expect_success 'stdin creates reflogs with --create-reflog' '
+ echo "create $outside $m" >stdin &&
+ git update-ref --create-reflog --stdin <stdin &&
+ git rev-parse $m >expect &&
+ git rev-parse $outside >actual &&
+ test_cmp expect actual &&
+ git reflog exists $outside
+'
+
test_expect_success 'stdin succeeds with quoted argument' '
git update-ref -d $a &&
echo "create $a \"$m\"" >stdin &&
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index d1ff5c9..426d285 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -51,7 +51,14 @@ test_expect_success 'creating a tag using default HEAD should succeed' '
echo foo >foo &&
git add foo &&
git commit -m Foo &&
- git tag mytag
+ git tag mytag &&
+ test_must_fail git reflog exists refs/tags/mytag
+'
+
+test_expect_success 'creating a tag with --create-reflog should create reflog' '
+ test_when_finished "git tag -d tag_with_reflog" &&
+ git tag --create-reflog tag_with_reflog &&
+ git reflog exists refs/tags/tag_with_reflog
'
test_expect_success 'listing all tags if one exists should succeed' '
--
2.0.5.499.g01f6352.dirty-twtrsrc
next prev parent reply other threads:[~2015-07-08 0:56 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-08 0:55 [PATCH v7 1/8] refs.c: add err arguments to reflog functions David Turner
2015-07-08 0:55 ` [PATCH v7 2/8] cherry-pick: treat CHERRY_PICK_HEAD and REVERT_HEAD as refs David Turner
2015-07-08 17:46 ` Johannes Sixt
2015-07-08 19:16 ` David Turner
2015-07-08 21:14 ` Johannes Sixt
2015-07-08 23:23 ` Junio C Hamano
2015-07-08 23:44 ` David Turner
2015-07-09 5:55 ` Junio C Hamano
2015-07-09 21:53 ` David Turner
2015-07-09 22:06 ` Junio C Hamano
2015-07-10 4:30 ` Michael Haggerty
2015-07-10 17:59 ` David Turner
2015-07-14 4:33 ` David Turner
2015-07-15 16:24 ` Junio C Hamano
2015-07-15 18:04 ` David Turner
2015-07-08 23:41 ` David Turner
2015-07-08 0:55 ` [PATCH v7 3/8] bisect: treat BISECT_HEAD as a ref David Turner
2015-07-08 0:55 ` [PATCH v7 4/8] refs: Break out check for reflog autocreation David Turner
2015-07-08 0:56 ` [PATCH v7 5/8] refs: new public ref function: safe_create_reflog David Turner
2015-07-08 11:49 ` Michael Haggerty
2015-07-08 0:56 ` [PATCH v7 6/8] git-reflog: add exists command David Turner
2015-07-08 0:56 ` David Turner [this message]
2015-07-08 13:44 ` [PATCH v7 7/8] update-ref and tag: add --create-reflog arg Michael Haggerty
2015-07-08 20:21 ` David Turner
2015-07-08 0:56 ` [PATCH v7 8/8] git-stash: use update-ref --create-reflog instead of creating files David Turner
2015-07-08 7:28 ` Junio C Hamano
2015-07-08 7:33 ` Junio C Hamano
2015-07-08 13:50 ` Michael Haggerty
2015-07-08 11:36 ` [PATCH v7 1/8] refs.c: add err arguments to reflog functions Michael Haggerty
2015-07-08 20:01 ` David Turner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1436316963-25520-7-git-send-email-dturner@twopensource.com \
--to=dturner@twopensource.com \
--cc=git@vger.kernel.org \
--cc=mhagger@alum.mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).