[BUG] git describe returns wrong tag as closest tag
Hi! I've discovered that if you have two non-rewinding branches that you merge between you can get the wrong tag as closest tag if the COMMITTER_DATE of any of the commits after the branch split is before the date of the branch split. You can end up in this state simply by having a committer doing a rebase after a branch split and pushing their code. (This is an assumption of what happened when we saw the behaviour) Reproduction case: mkdir testcase cd testcase git init git commit --allow-empty -m init git tag -a -m 'Test tag 1' 1 git branch tagerror git checkout tagerror git commit --allow-empty -m test01 git commit --allow-empty -m test02 git checkout master GIT_COMMITTER_DATE=`date --date '-10 min'` git commit --allow-empty -m test03 # this is what causes the error git tag -a -m 'Test tag 2' 2 git checkout tagerror git commit --allow-empty -m test04 git checkout master git merge --no-ff tagerror git describe --long # (expected output is '2-4-COMMITHASH', output is '1-5-COMMITHASH') If you remove the GIT_COMMITTER_DATE from the repro, you'll notice that you get the expected output. You can verify the ANY part by adding a commit on each branch before the COMMITTER_DATE like this: mkdir testcase cd testcase git init git commit --allow-empty -m init git tag -a -m 'Test tag 1' 1 git branch tagerror git checkout tagerror git commit --allow-empty -m test01 git commit --allow-empty -m test02 git commit --allow-empty -m test03 git checkout master git commit --allow-empty -m test04 git tag -a -m 'Test tag 2' 2 GIT_COMMITTER_DATE=`date --date '-10 min'` git commit --allow-empty -m test05 # this is what causes the error git checkout tagerror git commit --allow-empty -m test06 git checkout master git merge --no-ff tagerror git describe --long # (expected output is '2-4-COMMITHASH', output is '1-5-COMMITHASH') If you run a git describe --long --first-parent, you'll notice that it does actually pick up the correct tag in both above cases. It seems to me that in the source code for describe, it relies on sorting the commits on a strict date basis, rather than sorting them in traversal order: https://github.com/git/git/blob/master/builtin/describe.c#L204 Caveats to the reproduction case: In our real case, the date of the commit causing the issue is before the last commit before the branch split, but not before the root commit nor before tag 1 in the repro case. The distance to the tag that is erroneously picked up is much greater than the closest tag (around 1200 commits more). I'm sadly not very well-versed in C nor in the Git source code, so I'm not sure how the appropriate fix would look like - that's why I'm not also submitting a patch to fix this. :) // Mikael K. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] commit: add commit.signoff config option
From: Caio Marcelo de Oliveira Filho cmarc...@gmail.com In projects that use Signed-off-by, it's convenient to include that line in the commit by default. The commit.signoff config option allows to add that line in all commits automatically. Document that this config option can be overriden by using --no-signoff. Signed-off-by: Caio Marcelo de Oliveira Filho cmarc...@gmail.com --- Documentation/config.txt | 6 ++ Documentation/git-commit.txt | 5 + builtin/commit.c | 4 t/t7500-commit.sh| 22 ++ 4 files changed, 37 insertions(+) diff --git a/Documentation/config.txt b/Documentation/config.txt index 3e37b93..e019f62 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1089,6 +1089,12 @@ commit.gpgSign:: convenient to use an agent to avoid typing your GPG passphrase several times. +commit.signoff:: + + A boolean to enable/disable whether Signed-off-by line by the + committer should be added to all commits at the end of the + commit log messages. Defaults to false. + commit.status:: A boolean to enable/disable inclusion of status information in the commit message template when using an editor to prepare the commit diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 904dafa..7546c7a 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -156,6 +156,11 @@ OPTIONS Add Signed-off-by line by the committer at the end of the commit log message. +--no-signoff:: + Countermand `commit.signoff` configuration, preventing a + Signed-off-by line to be added at the end of the commit log + message. + -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks. diff --git a/builtin/commit.c b/builtin/commit.c index 254477f..5cfbe57 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1505,6 +1505,10 @@ static int git_commit_config(const char *k, const char *v, void *cb) sign_commit = git_config_bool(k, v) ? : NULL; return 0; } + if (!strcmp(k, commit.signoff)) { + signoff = git_config_bool(k, v); + return 0; + } status = git_gpg_config(k, v, NULL); if (status) diff --git a/t/t7500-commit.sh b/t/t7500-commit.sh index 116885a..fcb39b4 100755 --- a/t/t7500-commit.sh +++ b/t/t7500-commit.sh @@ -179,6 +179,28 @@ test_expect_success '--signoff' ' test_cmp expect output ' +test_expect_success 'commit.signoff config option' ' + git config commit.signoff true + echo yet another content *narf* foo + echo zort | git commit -F - foo + git cat-file commit HEAD | sed 1,/^\$/d output + git config --unset commit.signoff + test_cmp expect output +' + +cat expect EOF +no signed off by here +EOF + +test_expect_success '--no-signoff' ' + git config commit.signoff true + echo yet another content *narf* foo + echo no signed off by here | git commit --no-signoff -F - foo + git cat-file commit HEAD | sed 1,/^\$/d output + git config --unset commit.signoff + test_cmp expect output +' + test_expect_success 'commit message from file (1)' ' mkdir subdir echo Log in top directory log -- 2.4.4.489.gc2a2b54.dirty -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] commit: add commit.signoff config option
In projects that use Signed-off-by, it's convenient to include that line in the commit by default. The commit.signoff config option allows to add that line in all commits automatically. Document that this config option can be overriden by using --no-signoff. Signed-off-by: Caio Marcelo de Oliveira Filho cmarc...@gmail.com --- Documentation/config.txt | 6 ++ Documentation/git-commit.txt | 5 + builtin/commit.c | 4 t/t7500-commit.sh| 22 ++ 4 files changed, 37 insertions(+) diff --git a/Documentation/config.txt b/Documentation/config.txt index 3e37b93..e019f62 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1089,6 +1089,12 @@ commit.gpgSign:: convenient to use an agent to avoid typing your GPG passphrase several times. +commit.signoff:: + + A boolean to enable/disable whether Signed-off-by line by the + committer should be added to all commits at the end of the + commit log messages. Defaults to false. + commit.status:: A boolean to enable/disable inclusion of status information in the commit message template when using an editor to prepare the commit diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 904dafa..7546c7a 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -156,6 +156,11 @@ OPTIONS Add Signed-off-by line by the committer at the end of the commit log message. +--no-signoff:: + Countermand `commit.signoff` configuration, preventing a + Signed-off-by line to be added at the end of the commit log + message. + -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks. diff --git a/builtin/commit.c b/builtin/commit.c index 254477f..5cfbe57 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1505,6 +1505,10 @@ static int git_commit_config(const char *k, const char *v, void *cb) sign_commit = git_config_bool(k, v) ? : NULL; return 0; } + if (!strcmp(k, commit.signoff)) { + signoff = git_config_bool(k, v); + return 0; + } status = git_gpg_config(k, v, NULL); if (status) diff --git a/t/t7500-commit.sh b/t/t7500-commit.sh index 116885a..fcb39b4 100755 --- a/t/t7500-commit.sh +++ b/t/t7500-commit.sh @@ -179,6 +179,28 @@ test_expect_success '--signoff' ' test_cmp expect output ' +test_expect_success 'commit.signoff config option' ' + git config commit.signoff true + echo yet another content *narf* foo + echo zort | git commit -F - foo + git cat-file commit HEAD | sed 1,/^\$/d output + git config --unset commit.signoff + test_cmp expect output +' + +cat expect EOF +no signed off by here +EOF + +test_expect_success '--no-signoff' ' + git config commit.signoff true + echo yet another content *narf* foo + echo no signed off by here | git commit --no-signoff -F - foo + git cat-file commit HEAD | sed 1,/^\$/d output + git config --unset commit.signoff + test_cmp expect output +' + test_expect_success 'commit message from file (1)' ' mkdir subdir echo Log in top directory log -- 2.4.4.489.gc2a2b54.dirty -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 01/17] .gitignore: improve MSVC ignore patterns
From: Junio C Hamano gits...@pobox.com Philip Oakley philipoak...@iee.org writes: Add the Microsoft .manifest pattern, and correct the generic 'Debug' and 'Release' directory patterns which were mechanically adjusted way back in c591d5f (gitignore: root most patterns at the top-level directory, 2009-10-26) to allow multi-level projects within the Git suite. Signed-off-by: Philip Oakley philipoak...@iee.org --- .gitignore | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 422c538..55498c1 100644 --- a/.gitignore +++ b/.gitignore @@ -246,5 +246,6 @@ *.user *.idb *.pdb -/Debug/ -/Release/ +*.manifest +**/Debug/ +**/Release/ Why **/ there? Wouldn't *.manifest Debug/ Release/ suffice? Probably. I was thinking of the 'at any level' aspect because some of the 'projects' appeared two levels down and weren't caught by the rooted ignore. Can change. -- Philip -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: git error in tag ...: unterminated header
Dear Junio, thanks for the fast replies. In message xmqqegkzzoaz@gitster.dls.corp.google.com you wrote: Question is: how can we fix that? It could be that 4d0d8975 is buggy and barking at a non breakage. If there is no message in the tag, i.e. -- 8 -- object 84ef51a632063e8cb57b2e9a4252497512831ffe type commit tag LABEL_2006_03_12_0025 tagger Wolfgang Denk w...@pollux.denx.de 1142119613 +0100 -- 8 -- It seems recent tools cannot create such tags any more? I do not offhand see why we want to require that there is a lone blank line at the end. Hm... it seems I cannot even easily delte these tags: - git tag -d LABEL_2006_03_12_0025 Deleted tag 'LABEL_2006_03_12_0025' (was eb394f5) - git fsck --full Checking object directories: 100% (256/256), done. Checking object directories: 100% (256/256), done. error in tag eb394f56db3e05d00891d6dc36a00df0025cf255: unterminated header error in tag 9bf86baaa3b35b25baa2d664e2f7f6cafad689ee: unterminated header error in tag c7071e6d645a8e13adb0d4cea2caad27213fa62f: unterminated header error in tag eb394f56db3e05d00891d6dc36a00df0025cf255: unterminated header error in tag 9bf86baaa3b35b25baa2d664e2f7f6cafad689ee: unterminated header error in tag c7071e6d645a8e13adb0d4cea2caad27213fa62f: unterminated header Checking objects: 100% (657288/657288), done. Checking connectivity: 325718, done. dangling tag eb394f56db3e05d00891d6dc36a00df0025cf255 Now I also have this dangling tag thingy... Best regards, Wolfgang Denk -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: w...@denx.de An organization dries up if you don't challenge it with growth. - Mark Shepherd, former President and CEO of Texas Instruments -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/6] git-reflog: add create and exists functions
On Thu, 2015-06-25 at 11:35 -0700, Junio C Hamano wrote: Junio C Hamano gits...@pobox.com writes: Now, going back to 4/6, I think create_reflog() function as an external API has a few problems. * Its name does not tell us what should happen when a reflog already exists for the refname the caller asked to create reflog for. I understand that this only makes sure it exists and does not destroy existing one. Its old name, log_ref_setup(), did not have this problem, but now it does. ... * Add a thin-wrapper for callers that do not care about the path to the log file, e.g. int vivify_reflog(const char *refname, struct strbuf *err) { As usual, I am aware that I am not good at naming things (but I can tell when somebody uses a bad name), and vivify may be a horrible name for that. A reroll with a better name is very much welcomed. Perhaps prepare-reflog? I dunno. I'll try safe_create_reflog, by analogy to safe_create_leading_dirs. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 3/6] bisect: use refs infrastructure for BISECT_START
This ref needs to go through the refs backend, since some code assumes that it can be written and read as a ref. Signed-off-by: David Turner dtur...@twopensource.com --- contrib/completion/git-completion.bash | 2 +- git-bisect.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 93716c4..c4d4d80 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -938,7 +938,7 @@ _git_bisect () local subcommands=start bad good skip reset visualize replay log run local subcommand=$(__git_find_on_cmdline $subcommands) if [ -z $subcommand ]; then - if [ -f $(__gitdir)/BISECT_START ]; then + if [ git rev-parse BISECT_START 2/dev/null ]; then __gitcomp $subcommands else __gitcomp replay start diff --git a/git-bisect.sh b/git-bisect.sh index ae3fec2..8658772 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -166,7 +166,7 @@ bisect_start() { # echo $start_head $GIT_DIR/BISECT_START { test z$mode != z--no-checkout || - git update-ref --no-deref BISECT_HEAD $start_head + git rev-parse $start_head $GIT_DIR/BISECT_HEAD } git rev-parse --sq-quote $@ $GIT_DIR/BISECT_NAMES eval $eval true @@ -399,7 +399,7 @@ bisect_clean_state() { rm -f $GIT_DIR/BISECT_RUN # Cleanup head-name if it got left by an old version of git-bisect rm -f $GIT_DIR/head-name - git update-ref -d --no-deref BISECT_HEAD + rm -f $GIT_DIR/BISECT_HEAD # clean up BISECT_START last rm -f $GIT_DIR/BISECT_START } -- 2.0.4.314.gdbf7a51-twtrsrc -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/6] refs.c: add err arguments to reflog functions
Add an err argument to log_ref_setup that can explain the reason for a failure. This then eliminates the need to manage errno through this function since we can just add strerror(errno) to the err string when meaningful. No callers relied on errno from this function for anything else than the error message. Also add err arguments to private functions write_ref_to_lockfile, log_ref_write_1, commit_ref_update. This again eliminates the need to manage errno in these functions. Update of a patch by Ronnie Sahlberg. Signed-off-by: Ronnie Sahlberg sahlb...@google.com Signed-off-by: David Turner dtur...@twitter.com --- builtin/checkout.c | 8 ++-- refs.c | 111 - refs.h | 4 +- 3 files changed, 66 insertions(+), 57 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index c018ab3..93f63d3 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -624,16 +624,18 @@ static void update_refs_for_switch(const struct checkout_opts *opts, struct strbuf log_file = STRBUF_INIT; int ret; const char *ref_name; + struct strbuf err = STRBUF_INIT; ref_name = mkpath(refs/heads/%s, opts-new_orphan_branch); temp = log_all_ref_updates; log_all_ref_updates = 1; - ret = log_ref_setup(ref_name, log_file); + ret = log_ref_setup(ref_name, log_file, err); log_all_ref_updates = temp; strbuf_release(log_file); if (ret) { - fprintf(stderr, _(Can not do reflog for '%s'\n), - opts-new_orphan_branch); + fprintf(stderr, _(Can not do reflog for '%s'. %s\n), + opts-new_orphan_branch, err.buf); + strbuf_release(err); return; } } diff --git a/refs.c b/refs.c index fb568d7..b34a54a 100644 --- a/refs.c +++ b/refs.c @@ -2975,9 +2975,11 @@ static int rename_ref_available(const char *oldname, const char *newname) return ret; } -static int write_ref_to_lockfile(struct ref_lock *lock, const unsigned char *sha1); +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, -const unsigned char *sha1, const char *logmsg); +const unsigned char *sha1, const char *logmsg, +struct strbuf *err); int rename_ref(const char *oldrefname, const char *newrefname, const char *logmsg) { @@ -3038,9 +3040,10 @@ 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) || - commit_ref_update(lock, orig_sha1, logmsg)) { - error(unable to write current sha1 into %s, newrefname); + if (write_ref_to_lockfile(lock, orig_sha1, err) || + commit_ref_update(lock, orig_sha1, logmsg, err)) { + error(unable to write current sha1 into %s: %s, newrefname, err.buf); + strbuf_release(err); goto rollback; } @@ -3056,9 +3059,11 @@ 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) || - commit_ref_update(lock, orig_sha1, NULL)) - error(unable to write current sha1 into %s, oldrefname); + if (write_ref_to_lockfile(lock, orig_sha1, err) || + commit_ref_update(lock, orig_sha1, NULL, err)) { + error(unable to write current sha1 into %s: %s, oldrefname, err.buf); + strbuf_release(err); + } log_all_ref_updates = flag; rollbacklog: @@ -3113,8 +3118,8 @@ static int copy_msg(char *buf, const char *msg) return cp - buf; } -/* This function must set a meaningful errno on failure */ -int log_ref_setup(const char *refname, struct strbuf *sb_logfile) +/* This function will fill in *err and return -1 on failure */ +int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf *err) { int logfd, oflags = O_APPEND | O_WRONLY; char *logfile; @@ -3129,9 +3134,8 @@ int log_ref_setup(const char *refname, struct strbuf *sb_logfile) starts_with(refname, refs/notes/) ||
[PATCH v2 4/6] refs: add safe_create_reflog function
Make log_ref_setup private, and add public safe_create_reflog which calls log_ref_setup. In a moment, we will use safe_create_reflog to add reflog creation commands to git-reflog. Signed-off-by: David Turner dtur...@twopensource.com --- builtin/checkout.c | 4 +--- refs.c | 11 +++ refs.h | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index 93f63d3..b793670 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -621,7 +621,6 @@ static void update_refs_for_switch(const struct checkout_opts *opts, if (opts-new_orphan_branch) { if (opts-new_branch_log !log_all_ref_updates) { int temp; - struct strbuf log_file = STRBUF_INIT; int ret; const char *ref_name; struct strbuf err = STRBUF_INIT; @@ -629,9 +628,8 @@ static void update_refs_for_switch(const struct checkout_opts *opts, ref_name = mkpath(refs/heads/%s, opts-new_orphan_branch); temp = log_all_ref_updates; log_all_ref_updates = 1; - ret = log_ref_setup(ref_name, log_file, err); + ret = safe_create_reflog(ref_name, err); log_all_ref_updates = temp; - strbuf_release(log_file); if (ret) { fprintf(stderr, _(Can not do reflog for '%s'. %s\n), opts-new_orphan_branch, err.buf); diff --git a/refs.c b/refs.c index de7b5ef..7b02c45 100644 --- a/refs.c +++ b/refs.c @@ -3171,6 +3171,17 @@ int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf return 0; } + +int safe_create_reflog(const char *refname, struct strbuf *err) +{ + int ret; + struct strbuf sb = STRBUF_INIT; + + ret = log_ref_setup(refname, sb, err); + strbuf_release(sb); + return ret; +} + static int log_ref_write_fd(int fd, const unsigned char *old_sha1, const unsigned char *new_sha1, const char *committer, const char *msg) diff --git a/refs.h b/refs.h index debdefc..2986aac 100644 --- a/refs.h +++ b/refs.h @@ -228,7 +228,7 @@ int pack_refs(unsigned int flags); /* * Setup reflog before using. Fill in err and return -1 on failure. */ -int log_ref_setup(const char *refname, struct strbuf *logfile, struct strbuf *err); +int safe_create_reflog(const char *refname, struct strbuf *err); /** Reads log for the value of ref during at_time. **/ extern int read_ref_at(const char *refname, unsigned int flags, -- 2.0.4.314.gdbf7a51-twtrsrc -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/6] cherry-pick: treat CHERRY_PICK_HEAD and REVERT_HEAD as refs
Instead of directly writing to and reading from files in $GIT_DIR, use ref API to interact with CHERRY_PICK_HEAD and REVERT_HEAD. Signed-off-by: David Turner dtur...@twopensource.com --- branch.c | 4 ++-- builtin/commit.c | 6 +++--- builtin/merge.c | 2 +- contrib/completion/git-prompt.sh | 4 ++-- git-gui/lib/commit.tcl | 2 +- refs.c | 32 +++- sequencer.c | 37 +++-- t/t7509-commit.sh| 4 ++-- wt-status.c | 6 ++ 9 files changed, 51 insertions(+), 46 deletions(-) diff --git a/branch.c b/branch.c index b002435..ec598aa 100644 --- a/branch.c +++ b/branch.c @@ -302,8 +302,8 @@ void create_branch(const char *head, void remove_branch_state(void) { - unlink(git_path(CHERRY_PICK_HEAD)); - unlink(git_path(REVERT_HEAD)); + delete_ref(CHERRY_PICK_HEAD, NULL, REF_NODEREF); + delete_ref(REVERT_HEAD, NULL, REF_NODEREF); unlink(git_path(MERGE_HEAD)); unlink(git_path(MERGE_RR)); unlink(git_path(MERGE_MSG)); diff --git a/builtin/commit.c b/builtin/commit.c index b5b1158..53c7e90 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -168,7 +168,7 @@ static void determine_whence(struct wt_status *s) { if (file_exists(git_path(MERGE_HEAD))) whence = FROM_MERGE; - else if (file_exists(git_path(CHERRY_PICK_HEAD))) { + else if (ref_exists(CHERRY_PICK_HEAD)) { whence = FROM_CHERRY_PICK; if (file_exists(git_path(SEQ_DIR))) sequencer_in_use = 1; @@ -1777,8 +1777,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix) } ref_transaction_free(transaction); - unlink(git_path(CHERRY_PICK_HEAD)); - unlink(git_path(REVERT_HEAD)); + delete_ref(CHERRY_PICK_HEAD, NULL, REF_NODEREF); + delete_ref(REVERT_HEAD, NULL, REF_NODEREF); unlink(git_path(MERGE_HEAD)); unlink(git_path(MERGE_MSG)); unlink(git_path(MERGE_MODE)); diff --git a/builtin/merge.c b/builtin/merge.c index 46aacd6..3e2ae2f 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -1206,7 +1206,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) else die(_(You have not concluded your merge (MERGE_HEAD exists).)); } - if (file_exists(git_path(CHERRY_PICK_HEAD))) { + if (ref_exists(CHERRY_PICK_HEAD)) { if (advice_resolve_conflict) die(_(You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n Please, commit your changes before you merge.)); diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index 366f0bc..e2c5583 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -415,9 +415,9 @@ __git_ps1 () fi elif [ -f $g/MERGE_HEAD ]; then r=|MERGING - elif [ -f $g/CHERRY_PICK_HEAD ]; then + elif git rev-parse --quiet --verify CHERRY_PICK_HEAD /dev/null; then r=|CHERRY-PICKING - elif [ -f $g/REVERT_HEAD ]; then + elif git rev-parse --quiet --verify REVERT_HEAD /dev/null; then r=|REVERTING elif [ -f $g/BISECT_LOG ]; then r=|BISECTING diff --git a/git-gui/lib/commit.tcl b/git-gui/lib/commit.tcl index 864b687..2b08b13 100644 --- a/git-gui/lib/commit.tcl +++ b/git-gui/lib/commit.tcl @@ -409,7 +409,7 @@ A rescan will be automatically started now. catch {file delete [gitdir MERGE_MSG]} catch {file delete [gitdir SQUASH_MSG]} catch {file delete [gitdir GITGUI_MSG]} - catch {file delete [gitdir CHERRY_PICK_HEAD]} + catch {git update-ref -d --no-deref CHERRY_PICK_HEAD} # -- Let rerere do its thing. # diff --git a/refs.c b/refs.c index b34a54a..de7b5ef 100644 --- a/refs.c +++ b/refs.c @@ -2979,7 +2979,7 @@ 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, const unsigned char *sha1, const char *logmsg, -struct strbuf *err); +struct strbuf *err, int flags); int rename_ref(const char *oldrefname, const char *newrefname, const char *logmsg) { @@ -3041,7 +3041,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(lock, orig_sha1,
[PATCH v2 6/6] git-stash: use git-reflog instead of creating files
This is in support of alternate ref backends which don't necessarily store reflogs as files. Signed-off-by: David Turner dtur...@twopensource.com --- git-stash.sh | 4 ++-- refs.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/git-stash.sh b/git-stash.sh index 8e9e2cd..27155bc 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -184,7 +184,7 @@ store_stash () { fi # Make sure the reflog for stash is kept. - : $(git rev-parse --git-path logs/$ref_stash) + git reflog create $ref_stash git update-ref -m $stash_msg $ref_stash $w_commit ret=$? test $ret != 0 test -z $quiet @@ -262,7 +262,7 @@ save_stash () { say $(gettext No local changes to save) exit 0 fi - test -f $(git rev-parse --git-path logs/$ref_stash) || + git reflog exists $ref_stash || clear_stash || die $(gettext Cannot initialize stash) create_stash $stash_msg $untracked diff --git a/refs.c b/refs.c index 7b02c45..e11a32b 100644 --- a/refs.c +++ b/refs.c @@ -3123,6 +3123,7 @@ static int should_autocreate_reflog(const char *refname) return starts_with(refname, refs/heads/) || starts_with(refname, refs/remotes/) || starts_with(refname, refs/notes/) || + !strcmp(refname, refs/stash) || !strcmp(refname, HEAD); } -- 2.0.4.314.gdbf7a51-twtrsrc -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 5/6] git-reflog: add create and exists functions
These are necessary because ref backends manage reflogs. In a moment, we will use these functions to make git stash work with alternate ref backends. Signed-off-by: David Turner dtur...@twopensource.com --- builtin/reflog.c | 79 +++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/builtin/reflog.c b/builtin/reflog.c index c2eb8ff..a64158d 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -13,6 +13,10 @@ static const char reflog_expire_usage[] = git reflog expire [--expire=time] [--expire-unreachable=time] [--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] [--verbose] [--all] refs...; static const char reflog_delete_usage[] = git reflog delete [--rewrite] [--updateref] [--dry-run | -n] [--verbose] refs...; +static const char reflog_create_usage[] = +git reflog create refs...; +static const char reflog_exists_usage[] = +git reflog exists refs...; static unsigned long default_reflog_expire; static unsigned long default_reflog_expire_unreachable; @@ -699,12 +703,79 @@ static int cmd_reflog_delete(int argc, const char **argv, const char *prefix) return status; } +static int cmd_reflog_create(int argc, const char **argv, const char *prefix) +{ + int i, status = 0, start = 0; + struct strbuf err = STRBUF_INIT; + + for (i = 1; i argc; i++) { + const char *arg = argv[i]; + if (!strcmp(arg, --)) { + i++; + break; + } + else if (arg[0] == '-') + usage(reflog_create_usage); + else + break; + } + + start = i; + + if (argc - start 1) + return error(Nothing to create?); + + for (i = start ; i argc; i++) { + if (check_refname_format(argv[i], REFNAME_ALLOW_ONELEVEL)) + die(invalid ref format: %s, argv[i]); + } + for (i = start ; i argc; i++) { + if (safe_create_reflog(argv[i], err)) { + error(could not create reflog %s: %s, argv[i], + err.buf); + status = 1; + strbuf_release(err); + } + } + return status; +} + +static int cmd_reflog_exists(int argc, const char **argv, const char *prefix) +{ + int i, status = 0, start = 0; + + for (i = 1; i argc; i++) { + const char *arg = argv[i]; + if (!strcmp(arg, --)) { + i++; + break; + } + else if (arg[0] == '-') + usage(reflog_exists_usage); + else + break; + } + + start = i; + + if (argc - start 1) + return error(Nothing to check?); + + for (i = start ; i argc; i++) { + if (check_refname_format(argv[i], REFNAME_ALLOW_ONELEVEL)) + die(invalid ref format: %s, argv[i]); + if (!reflog_exists(argv[i])) + status = 1; + } + return status; +} + /* * main reflog */ static const char reflog_usage[] = -git reflog [ show | expire | delete ]; +git reflog [ show | expire | delete | create | exists ]; int cmd_reflog(int argc, const char **argv, const char *prefix) { @@ -724,5 +795,11 @@ int cmd_reflog(int argc, const char **argv, const char *prefix) if (!strcmp(argv[1], delete)) return cmd_reflog_delete(argc - 1, argv + 1, prefix); + if (!strcmp(argv[1], create)) + return cmd_reflog_create(argc - 1, argv + 1, prefix); + + if (!strcmp(argv[1], exists)) + return cmd_reflog_exists(argc - 1, argv + 1, prefix); + return cmd_log_reflog(argc, argv, prefix); } -- 2.0.4.314.gdbf7a51-twtrsrc -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 01/17] .gitignore: improve MSVC ignore patterns
Philip Oakley philipoak...@iee.org writes: Debug/ Release/ suffice? Probably. I was thinking of the 'at any level' aspect... Yeah, that is exactly the difference between rooted /Debug/ and Debug/ ;-). -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 3/6] bisect: use refs infrastructure for BISECT_START
David Turner dtur...@twopensource.com writes: This ref needs to go through the refs backend, since some code assumes that it can be written and read as a ref. And the reason why BISECT_HEAD cannot be treated as a ref, but must be treated as a file under $GIT_DIR, is...? Signed-off-by: David Turner dtur...@twopensource.com --- contrib/completion/git-completion.bash | 2 +- git-bisect.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 93716c4..c4d4d80 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -938,7 +938,7 @@ _git_bisect () local subcommands=start bad good skip reset visualize replay log run local subcommand=$(__git_find_on_cmdline $subcommands) if [ -z $subcommand ]; then - if [ -f $(__gitdir)/BISECT_START ]; then + if [ git rev-parse BISECT_START 2/dev/null ]; then __gitcomp $subcommands else __gitcomp replay start diff --git a/git-bisect.sh b/git-bisect.sh index ae3fec2..8658772 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -166,7 +166,7 @@ bisect_start() { # echo $start_head $GIT_DIR/BISECT_START { test z$mode != z--no-checkout || - git update-ref --no-deref BISECT_HEAD $start_head + git rev-parse $start_head $GIT_DIR/BISECT_HEAD } git rev-parse --sq-quote $@ $GIT_DIR/BISECT_NAMES eval $eval true @@ -399,7 +399,7 @@ bisect_clean_state() { rm -f $GIT_DIR/BISECT_RUN # Cleanup head-name if it got left by an old version of git-bisect rm -f $GIT_DIR/head-name - git update-ref -d --no-deref BISECT_HEAD + rm -f $GIT_DIR/BISECT_HEAD # clean up BISECT_START last rm -f $GIT_DIR/BISECT_START } -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
several date related issues
Running 2.4.4 *** Dates do not respect LC_TIME $ date Thu 25 Jun 2015 13:02:48 CEST $ git log --pretty=fuller --date=local | head -6 | grep -i date AuthorDate: Mon Feb 16 16:47:08 2015 CommitDate: Mon Feb 16 16:47:08 2015 $ locale -ck LC_TIME | grep fmt d_t_fmt=%a %d %b %Y %r %Z d_fmt=%d-%m-%Y t_fmt=%r t_fmt_ampm=%H:%M:%S era_d_fmt= era_d_t_fmt= era_t_fmt= date_fmt=%a %e %b %Y %H:%M:%S %Z *** git log --date-order and --author-date-order do not order by date $ mkdir git-test $ cd git-test $ git init Initialized empty Git repository in /home/merijn/git-test/.git/ $ touch foo $ git add foo $ git commit -m boo [master (root-commit) 09483e5] boo 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 foo $ git log | cat commit 09483e527d6a4d4a9e49f82a11871ab55133cf72 Author: H.Merijn Brand h.m.br...@xs4all.nl Date: Thu Jun 25 13:14:37 2015 +0200 boo $ touch bar $ env GIT_AUTHOR_DATE=2015-01-15 12:13:14 GIT_COMMITTER_DATE=2015-01-15 12:13:14 git add bar $ env GIT_AUTHOR_DATE=2015-01-15 12:13:14 GIT_COMMITTER_DATE=2015-01-15 12:13:14 git commit -m Commit in past [master 6acc7f3] Commit in past 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 bar $ git log | cat commit 6acc7f3d2cbaca7176b63ffac51005ce07b90b91 Author: H.Merijn Brand h.m.br...@xs4all.nl Date: Thu Jan 15 12:13:14 2015 +0100 Commit in past commit 09483e527d6a4d4a9e49f82a11871ab55133cf72 Author: H.Merijn Brand h.m.br...@xs4all.nl Date: Thu Jun 25 13:14:37 2015 +0200 boo $ git log --date-order | cat commit 6acc7f3d2cbaca7176b63ffac51005ce07b90b91 Author: H.Merijn Brand h.m.br...@xs4all.nl Date: Thu Jan 15 12:13:14 2015 +0100 Commit in past commit 09483e527d6a4d4a9e49f82a11871ab55133cf72 Author: H.Merijn Brand h.m.br...@xs4all.nl Date: Thu Jun 25 13:14:37 2015 +0200 boo $ git log --author-date-order | cat commit 6acc7f3d2cbaca7176b63ffac51005ce07b90b91 Author: H.Merijn Brand h.m.br...@xs4all.nl Date: Thu Jan 15 12:13:14 2015 +0100 Commit in past commit 09483e527d6a4d4a9e49f82a11871ab55133cf72 Author: H.Merijn Brand h.m.br...@xs4all.nl Date: Thu Jun 25 13:14:37 2015 +0200 boo $ -- H.Merijn Brand http://tux.nl Perl Monger http://amsterdam.pm.org/ using perl5.00307 .. 5.21 porting perl5 on HP-UX, AIX, and openSUSE http://mirrors.develooper.com/hpux/http://www.test-smoke.org/ http://qa.perl.org http://www.goldmark.org/jeff/stupid-disclaimers/ pgp3fItiz4OQ5.pgp Description: OpenPGP digital signature
Re: [PATCH/WIP v3 06/31] am: detect mbox patches
On Wed, Jun 24, 2015 at 11:10 PM, Johannes Schindelin johannes.schinde...@gmx.de wrote: Hi Paul, On 2015-06-18 13:25, Paul Tan wrote: diff --git a/builtin/am.c b/builtin/am.c index e9a3687..7b97ea8 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -121,6 +121,96 @@ static void am_destroy(const struct am_state *state) strbuf_release(sb); } +/* + * Returns 1 if the file looks like a piece of email a-la RFC2822, 0 otherwise. + * We check this by grabbing all the non-indented lines and seeing if they look + * like they begin with valid header field names. + */ +static int is_email(const char *filename) +{ + struct strbuf sb = STRBUF_INIT; + FILE *fp = xfopen(filename, r); + int ret = 1; + + while (!strbuf_getline(sb, fp, '\n')) { + const char *x; + + strbuf_rtrim(sb); + + if (!sb.len) + break; /* End of header */ + + /* Ignore indented folded lines */ + if (*sb.buf == '\t' || *sb.buf == ' ') + continue; + + /* It's a header if it matches the regexp ^[!-9;-~]+: */ Why not just compile a regex and use it here? We use regexes elsewhere anyway... Ah, you're right. A regular expression would definitely be clearer. I've fixed it on my end. +/** + * Attempts to detect the patch_format of the patches contained in `paths`, + * returning the PATCH_FORMAT_* enum value. Returns PATCH_FORMAT_UNKNOWN if + * detection fails. + */ +static int detect_patch_format(struct string_list *paths) +{ + enum patch_format ret = PATCH_FORMAT_UNKNOWN; + struct strbuf l1 = STRBUF_INIT; + struct strbuf l2 = STRBUF_INIT; + struct strbuf l3 = STRBUF_INIT; + FILE *fp; + + /* + * We default to mbox format if input is from stdin and for directories + */ + if (!paths-nr || !strcmp(paths-items-string, -) || + is_directory(paths-items-string)) { + ret = PATCH_FORMAT_MBOX; + goto done; + } + + /* + * Otherwise, check the first 3 lines of the first patch, starting + * from the first non-blank line, to try to detect its format. + */ + fp = xfopen(paths-items-string, r); + while (!strbuf_getline(l1, fp, '\n')) { + strbuf_trim(l1); + if (l1.len) + break; + } + strbuf_getline(l2, fp, '\n'); We should test the return value of `strbuf_getline()`; if EOF was reached already, `strbuf_getwholeline()` does not touch the strbuf. I know, the strbuf is still initialized empty here, but it is too easy to forget when changing this code. Ah OK. I'll vote for doing a strbuf_reset() just before the strbuf_getline() though. + strbuf_trim(l2); + strbuf_getline(l3, fp, '\n'); + strbuf_trim(l3); + fclose(fp); + + if (starts_with(l1.buf, From ) || starts_with(l1.buf, From: )) + ret = PATCH_FORMAT_MBOX; Hmm. We can test that earlier and return without reading from the file any further, I think. The reading 3 lines at the beginning logic is meant to support a later patch where support for StGit and mercurial patches is added. That said, it's true that we don't need to read 3 lines in this patch, so I think I will remove it in this patch. + else if (l1.len l2.len l3.len is_email(paths-items-string)) + ret = PATCH_FORMAT_MBOX; Maybe we can do better than this by folding the `is_email() function into this here function, reusing the same strbuf to read the lines and keeping track of the email header lines we saw... I would really like to avoid opening the same file twice just to figure out whether it is in email format. Okay, how about every time we call a strbuf_getline(), we save the line to a string_list as well? Like string_list_getline_crlf() below: /** * Like strbuf_getline(), but supports both '\n' and \r\n as line * terminators. */ static int strbuf_getline_crlf(struct strbuf *sb, FILE *fp) { if (strbuf_getwholeline(sb, fp, '\n')) return EOF; if (sb-buf[sb-len - 1] == '\n') { strbuf_setlen(sb, sb-len - 1); if (sb-len 0 sb-buf[sb-len - 1] == '\r') strbuf_setlen(sb, sb-len - 1); } return 0; } /** * Like strbuf_getline_crlf(), but appends the line to a string_list and * returns it as a string. Returns NULL on EOF. */ static const char *string_list_getline_crlf(struct string_list *list, FILE *fp) { struct strbuf sb = STRBUF_INIT; struct string_list_item *item; if (strbuf_getline_crlf(sb, fp)) return NULL; item = string_list_append_nodup(list, strbuf_detach(sb, NULL)); return item-string; } So now, is_email() can have access to previously-read lines, and if it needs some more, it can read more as well: static int is_email(struct string_list *lines, FILE *fp) { const char *header_regex = ^[!-9;-~]+:; regex_t regex; int ret = 1;
[PATCH] blame: remove obsolete comment
That someday in the comment happened two years later in b65982b (Optimize diff-index --cached using cache-tree - 2009-05-20) Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com --- builtin/blame.c | 5 - 1 file changed, 5 deletions(-) diff --git a/builtin/blame.c b/builtin/blame.c index b3e948e..b077bb6 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -2371,11 +2371,6 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt, ce-ce_mode = create_ce_mode(mode); add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); - /* -* We are not going to write this out, so this does not matter -* right now, but someday we might optimize diff-index --cached -* with cache-tree information. -*/ cache_tree_invalidate_path(the_index, path); return commit; -- 2.3.0.rc1.137.g477eb31 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 5/9] ref-filter: add option to match literal pattern
Since 'ref-filter' only has an option to match path names. Add an option for regular pattern matching. Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- builtin/for-each-ref.c | 1 + ref-filter.c | 30 -- ref-filter.h | 3 ++- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index c318e33..01d5363 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -68,6 +68,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) git_config(git_default_config, NULL); filter.name_patterns = argv; + filter.match_as_path = 1; filter_refs(array, filter, FILTER_REFS_ALL | FILTER_REFS_INCLUDE_BROKEN); ref_array_sort(sorting, array); diff --git a/ref-filter.c b/ref-filter.c index e307fab..1f97910 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -954,6 +954,20 @@ static int commit_contains(struct ref_filter *filter, struct commit *commit) /* * Return 1 if the refname matches one of the patterns, otherwise 0. + * A pattern can be a literal prefix (e.g. a refname refs/heads/master + * matches a pattern refs/heads/m) or a wildcard (e.g. the same ref + * matches refs/heads/m*,too). + */ +static int match_pattern(const char **patterns, const char *refname) +{ + for (; *patterns; patterns++) + if (!wildmatch(*patterns, refname, 0, NULL)) + return 1; + return 0; +} + +/* + * Return 1 if the refname matches one of the patterns, otherwise 0. * A pattern can be path prefix (e.g. a refname refs/heads/master * matches a pattern refs/heads/) or a wildcard (e.g. the same ref * matches refs/heads/m*,too). @@ -977,6 +991,15 @@ static int match_name_as_path(const char **pattern, const char *refname) return 0; } +static int filter_pattern_match(struct ref_filter *filter, const char *refname) +{ + if (!*filter-name_patterns) + return 0; + if (filter-match_as_path) + return match_name_as_path(filter-name_patterns, refname); + return match_pattern(filter-name_patterns, refname); +} + /* * Given a ref (sha1, refname) see if it points to one of the sha1s * in a sha1_array. @@ -1026,17 +1049,12 @@ static int ref_filter_handler(const char *refname, const struct object_id *oid, struct ref_array_item *ref; struct commit *commit = NULL; - if (flag REF_BAD_NAME) { - warning(ignoring ref with broken name %s, refname); - return 0; - } - if (flag REF_ISBROKEN) { warning(ignoring broken ref %s, refname); return 0; } - if (*filter-name_patterns !match_name_as_path(filter-name_patterns, refname)) + if (!filter_pattern_match(filter, refname)) return 0; if (!match_points_at(filter-points_at, oid-hash, refname)) diff --git a/ref-filter.h b/ref-filter.h index 6b6fb96..a4809c8 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -54,7 +54,8 @@ struct ref_filter { } merge; struct commit *merge_commit; - unsigned int with_commit_tag_algo: 1; + unsigned int with_commit_tag_algo: 1, + match_as_path: 1; unsigned int lines; }; -- 2.4.4 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 7/9] tag.c: use 'ref-filter' APIs
Make 'tag.c' use 'ref-filter' APIs for iterating through refs sorting and printing of refs. This removes most of the code used in 'tag.c' replacing it with calls to the 'ref-filter' library. Make 'tag.c' use the 'filter_refs()' function provided by 'ref-filter' to filter out tags based on the options set. For printing tags we use 'show_ref_array_item()' function provided by 'ref-filter'. We improve the sorting option provided by 'tag.c' by using the sorting options provided by 'ref-filter'. This causes the test 'invalid sort parameter on command line' in t7004 to fail, as 'ref-filter' throws an error for all sorting fields which are incorrect. The test is changed to reflect the same. Modify documentation for the same. Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- Documentation/git-tag.txt | 16 ++- builtin/tag.c | 337 ++ t/t7004-tag.sh| 8 +- 3 files changed, 49 insertions(+), 312 deletions(-) diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index 034d10d..1950d94 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] [--sort=key] [pattern...] [pattern...] 'git tag' -v tagname... @@ -95,14 +95,16 @@ OPTIONS using fnmatch(3)). Multiple patterns may be given; if any of them matches, the tag is shown. ---sort=type:: - Sort in a specific order. Supported type is refname - (lexicographic order), version:refname or v:refname (tag +--sort=key:: + Sort based on the key given. Prefix `-` to sort in + descending order of the value. You may use the --sort=key option + multiple times, in which case the last key becomes the primary + key. Also supports version:refname or v:refname (tag names are treated as versions). The version:refname sort order can also be affected by the - versionsort.prereleaseSuffix configuration variable. Prepend - - to reverse sort order. When this option is not given, the - sort order defaults to the value configured for the 'tag.sort' + versionsort.prereleaseSuffix configuration variable. + The keys supported are the same as those in `git for-each-ref`. + Sort order defaults to the value configured for the 'tag.sort' variable if it exists, or lexicographic order otherwise. See linkgit:git-config[1]. diff --git a/builtin/tag.c b/builtin/tag.c index 65b6707..d80120e 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -28,273 +28,34 @@ static const char * const git_tag_usage[] = { NULL }; -#define STRCMP_SORT 0 /* must be zero */ -#define VERCMP_SORT 1 -#define SORT_MASK 0x7fff -#define REVERSE_SORT0x8000 - -static int tag_sort; - static unsigned int colopts; -static int match_pattern(const char **patterns, const char *ref) -{ - /* no pattern means match everything */ - if (!*patterns) - return 1; - for (; *patterns; patterns++) - if (!wildmatch(*patterns, ref, 0, NULL)) - return 1; - return 0; -} - -/* - * This is currently duplicated in ref-filter.c, and will eventually be - * removed as we port tag.c to use the ref-filter APIs. - */ -static const unsigned char *match_points_at(const char *refname, - const unsigned char *sha1, - struct sha1_array *points_at) -{ - const unsigned char *tagged_sha1 = NULL; - struct object *obj; - - if (sha1_array_lookup(points_at, sha1) = 0) - return sha1; - obj = parse_object(sha1); - if (!obj) - die(_(malformed object at '%s'), refname); - if (obj-type == OBJ_TAG) - tagged_sha1 = ((struct tag *)obj)-tagged-sha1; - if (tagged_sha1 sha1_array_lookup(points_at, tagged_sha1) = 0) - return tagged_sha1; - return NULL; -} - -static int in_commit_list(const struct commit_list *want, struct commit *c) -{ - for (; want; want = want-next) - if (!hashcmp(want-item-object.sha1, c-object.sha1)) - return 1; - return 0; -} - -enum contains_result { - CONTAINS_UNKNOWN = -1, - CONTAINS_NO = 0, - CONTAINS_YES = 1 -}; - -/* - * Test whether the candidate or one of its parents is contained in the list. - * Do not recurse to find out, though, but return -1 if inconclusive. - */ -static enum contains_result contains_test(struct commit *candidate, - const struct commit_list *want) -{ -
[RFC/PATCH 8/9] tag.c: implement '--format' option
Implement the '--format' option provided by 'ref-filter'. This lets the user list tags as per desired format similar to the implementation in 'git for-each-ref'. Add tests and documentation for the same. Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- Documentation/git-tag.txt | 15 ++- builtin/tag.c | 14 ++ t/t7004-tag.sh| 16 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index 1950d94..16e396c 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] [--sort=key] [pattern...] + [--column[=options] | --no-column] [--sort=key] [--format=format] [pattern...] 'git tag' -v tagname... @@ -156,6 +156,19 @@ This option is only applicable when listing tags without annotation lines. The object that the new tag will refer to, usually a commit. Defaults to HEAD. +format:: + A string that interpolates `%(fieldname)` from the + object pointed at by a ref being shown. If `fieldname` + is prefixed with an asterisk (`*`) and the ref points + at a tag object, the value for the field in the object + tag refers is used. When unspecified, defaults to + `%(objectname) SPC %(objecttype) TAB %(refname)`. + It also interpolates `%%` to `%`, and `%xx` where `xx` + are hex digits interpolates to character with hex code + `xx`; for example `%00` interpolates to `\0` (NUL), + `%09` to `\t` (TAB) and `%0a` to `\n` (LF). + The fields are same as those in `git for-each-ref`. + CONFIGURATION - diff --git a/builtin/tag.c b/builtin/tag.c index d80120e..91356c9 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -30,12 +30,14 @@ static const char * const git_tag_usage[] = { static unsigned int colopts; -static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting) +static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, const char *format) { struct ref_array array; - char *format; int i; + if (!format) + check_format = 1; + memset(array, 0, sizeof(array)); if (filter-lines == -1) @@ -43,7 +45,7 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting) if (filter-lines) format = %(refname:lalign16); - else + else if (!format) format = %(refname:short); verify_ref_format(format); @@ -324,6 +326,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) struct strbuf err = STRBUF_INIT; struct ref_filter filter; static struct ref_sorting *sorting = NULL, **sorting_tail = sorting; + const char *format = NULL; struct option options[] = { OPT_CMDMODE('l', list, cmdmode, N_(list tag names), 'l'), { OPTION_INTEGER, 'n', NULL, filter.lines, N_(n), @@ -355,6 +358,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) OPTION_CALLBACK, 0, points-at, filter.points_at, N_(object), N_(print only tags of the object), 0, parse_opt_object_name }, + OPT_STRING( 0 , format, format, N_(format), N_(format to use for the output)), OPT_END() }; @@ -394,8 +398,10 @@ int cmd_tag(int argc, const char **argv, const char *prefix) copts.padding = 2; run_column_filter(colopts, copts); } + if (format (filter.lines != -1)) + die(_(--format and -n are incompatible)); filter.name_patterns = argv; - ret = list_tags(filter, sorting); + ret = list_tags(filter, sorting, format); if (column_active(colopts)) stop_column_filter(); return ret; diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index 51a233f..e8cebb6 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1507,4 +1507,20 @@ EOF test_cmp expect actual ' +test_expect_success '--format cannot be used with -n' ' + test_must_fail git tag -l -n4 --format=%(refname) +' + +test_expect_success '--format should list tags as per format given' ' + cat expect -\EOF + foo1.10 + foo1.3 + foo1.6 + foo1.6-rc1 + foo1.6-rc2 + EOF + git tag -l --format=%(refname) foo* actual + test_cmp expect actual +' + test_done -- 2.4.4 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to
[RFC/PATCH 6/9] tag.c: use 'ref-filter' data structures
Make 'tag.c' use 'ref-filter' data structures and make changes to support the new data structures. This is a part of the process of porting 'tag.c' to use 'ref-filter' APIs. This is a temporary step before porting 'tag.c' to use 'ref-filter' completely. As this is a temporary step, most of the code introduced here will be removed when 'tag.c' is ported over to use 'ref-filter' APIs Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- builtin/tag.c | 106 +++--- 1 file changed, 57 insertions(+), 49 deletions(-) diff --git a/builtin/tag.c b/builtin/tag.c index 9f300e0..65b6707 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -17,6 +17,7 @@ #include gpg-interface.h #include sha1-array.h #include column.h +#include ref-filter.h static const char * const git_tag_usage[] = { N_(git tag [-a | -s | -u key-id] [-f] [-m msg | -F file] tagname [head]), @@ -34,15 +35,6 @@ static const char * const git_tag_usage[] = { static int tag_sort; -struct tag_filter { - const char **patterns; - int lines; - int sort; - struct string_list tags; - struct commit_list *with_commit; -}; - -static struct sha1_array points_at; static unsigned int colopts; static int match_pattern(const char **patterns, const char *ref) @@ -61,19 +53,20 @@ static int match_pattern(const char **patterns, const char *ref) * removed as we port tag.c to use the ref-filter APIs. */ static const unsigned char *match_points_at(const char *refname, - const unsigned char *sha1) + const unsigned char *sha1, + struct sha1_array *points_at) { const unsigned char *tagged_sha1 = NULL; struct object *obj; - if (sha1_array_lookup(points_at, sha1) = 0) + if (sha1_array_lookup(points_at, sha1) = 0) return sha1; obj = parse_object(sha1); if (!obj) die(_(malformed object at '%s'), refname); if (obj-type == OBJ_TAG) tagged_sha1 = ((struct tag *)obj)-tagged-sha1; - if (tagged_sha1 sha1_array_lookup(points_at, tagged_sha1) = 0) + if (tagged_sha1 sha1_array_lookup(points_at, tagged_sha1) = 0) return tagged_sha1; return NULL; } @@ -223,12 +216,24 @@ free_return: free(buf); } +static void ref_array_append(struct ref_array *array, const char *refname) +{ + size_t len = strlen(refname); + struct ref_array_item *ref = xcalloc(1, sizeof(struct ref_array_item) + len + 1); + memcpy(ref-refname, refname, len); + ref-refname[len] = '\0'; + REALLOC_ARRAY(array-items, array-nr + 1); + array-items[array-nr++] = ref; +} + static int show_reference(const char *refname, const struct object_id *oid, int flag, void *cb_data) { - struct tag_filter *filter = cb_data; + struct ref_filter_cbdata *data = cb_data; + struct ref_array *array = data-array; + struct ref_filter *filter = data-filter; - if (match_pattern(filter-patterns, refname)) { + if (match_pattern(filter-name_patterns, refname)) { if (filter-with_commit) { struct commit *commit; @@ -239,12 +244,12 @@ static int show_reference(const char *refname, const struct object_id *oid, return 0; } - if (points_at.nr !match_points_at(refname, oid-hash)) + if (filter-points_at.nr !match_points_at(refname, oid-hash, filter-points_at)) return 0; if (!filter-lines) { - if (filter-sort) - string_list_append(filter-tags, refname); + if (tag_sort) + ref_array_append(array, refname); else printf(%s\n, refname); return 0; @@ -259,36 +264,36 @@ static int show_reference(const char *refname, const struct object_id *oid, static int sort_by_version(const void *a_, const void *b_) { - const struct string_list_item *a = a_; - const struct string_list_item *b = b_; - return versioncmp(a-string, b-string); + const struct ref_array_item *a = *((struct ref_array_item **)a_); + const struct ref_array_item *b = *((struct ref_array_item **)b_); + return versioncmp(a-refname, b-refname); } -static int list_tags(const char **patterns, int lines, -struct commit_list *with_commit, int sort) +static int list_tags(struct ref_filter *filter, int sort) { - struct tag_filter filter; + struct ref_array array; + struct ref_filter_cbdata data; + +
[RFC/PATCH 2/9] ref-filter: add option to filter only tags
Add an option in 'filter_refs()' to use 'for_each_tag_ref()' and filter refs. This type checking is done by adding a 'FILTER_REFS_TAGS' in 'ref-filter.h' Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- ref-filter.c | 2 ++ ref-filter.h | 1 + 2 files changed, 3 insertions(+) diff --git a/ref-filter.c b/ref-filter.c index 299b048..97432d1 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -1141,6 +1141,8 @@ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int ret = for_each_rawref(ref_filter_handler, ref_cbdata); else if (type FILTER_REFS_ALL) ret = for_each_ref(ref_filter_handler, ref_cbdata); + else if (type FILTER_REFS_TAGS) + ret = for_each_tag_ref(ref_filter_handler, ref_cbdata); else if (type) die(filter_refs: invalid type); diff --git a/ref-filter.h b/ref-filter.h index 3c59431..dd28d17 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -15,6 +15,7 @@ #define FILTER_REFS_INCLUDE_BROKEN 0x1 #define FILTER_REFS_ALL 0x2 +#define FILTER_REFS_TAGS 0x4 struct atom_value { const char *s; -- 2.4.4 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 1/9] ref-filter: add %(refname:lalignX) option
Add support for %(refname:lalignX) where X is a number. This will print a shortened refname aligned to the left followed by spaces for a total length of X characters. If X is less than the shortened refname size, the entire shortened refname is printed. Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- ref-filter.c | 17 - 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/ref-filter.c b/ref-filter.c index 00d06bf..299b048 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -695,7 +695,22 @@ static void populate_value(struct ref_array_item *ref) int num_ours, num_theirs; formatp++; - if (!strcmp(formatp, short)) + if (starts_with(formatp, lalign)) { + const char *valp; + int val; + + skip_prefix(formatp, lalign, valp); + val = atoi(valp); + refname = shorten_unambiguous_ref(refname, + warn_ambiguous_refs); + if (val strlen(refname)) { + struct strbuf buf = STRBUF_INIT; + strbuf_addstr(buf, refname); + strbuf_addchars(buf, ' ', val - strlen(refname)); + free((char *)refname); + refname = strbuf_detach(buf, NULL); + } + } else if (!strcmp(formatp, short)) refname = shorten_unambiguous_ref(refname, warn_ambiguous_refs); else if (!strcmp(formatp, track) -- 2.4.4 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 3/9] ref-filter: support printing N lines from tag annotation
In 'tag.c' we can print N lines from the annotation of the tag using the '-nnum' option. Copy code from 'tag.c' to 'ref-filter' and modify 'ref-filter' to support printing of N lines from the annotation of tags. Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- builtin/for-each-ref.c | 2 +- builtin/tag.c | 4 ref-filter.c | 48 +++- ref-filter.h | 3 ++- 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 5868c48..c318e33 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -74,7 +74,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) if (!maxcount || array.nr maxcount) maxcount = array.nr; for (i = 0; i maxcount; i++) - show_ref_array_item(array.items[i], format, quote_style); + show_ref_array_item(array.items[i], format, quote_style, 0); ref_array_clear(array); return 0; } diff --git a/builtin/tag.c b/builtin/tag.c index 767162e..9f300e0 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -180,6 +180,10 @@ static enum contains_result contains(struct commit *candidate, return contains_test(candidate, want); } +/* + * Currently dupplicated in ref-filter, will eventually be removed as + * we port tag.c to use ref-filter APIs. + */ static void show_tag_lines(const struct object_id *oid, int lines) { int i; diff --git a/ref-filter.c b/ref-filter.c index 97432d1..57a5cfb 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -1262,7 +1262,48 @@ static void emit(const char *cp, const char *ep) } } -void show_ref_array_item(struct ref_array_item *info, const char *format, int quote_style) +/* Print 'lines' no of lines of a given oid */ +static void show_tag_lines(const struct object_id *oid, int lines) +{ + int i; + unsigned long size; + enum object_type type; + char *buf, *sp, *eol; + size_t len; + + buf = read_sha1_file(oid-hash, type, size); + if (!buf) + die_errno(unable to read object %s, oid_to_hex(oid)); + if (type != OBJ_COMMIT type != OBJ_TAG) + goto free_return; + if (!size) + die(an empty %s object %s?, + typename(type), oid_to_hex(oid)); + + /* skip header */ + sp = strstr(buf, \n\n); + if (!sp) + goto free_return; + + /* only take up to lines lines, and strip the signature from a tag */ + if (type == OBJ_TAG) + size = parse_signature(buf, size); + for (i = 0, sp += 2; i lines sp buf + size; i++) { + if (i) + printf(\n); + eol = memchr(sp, '\n', size - (sp - buf)); + len = eol ? eol - sp : size - (sp - buf); + fwrite(sp, len, 1, stdout); + if (!eol) + break; + sp = eol + 1; + } +free_return: + free(buf); +} + +void show_ref_array_item(struct ref_array_item *info, const char *format, +int quote_style, unsigned int lines) { const char *cp, *sp, *ep; @@ -1288,6 +1329,11 @@ void show_ref_array_item(struct ref_array_item *info, const char *format, int qu resetv.s = color; print_value(resetv, quote_style); } + if (lines 0) { + struct object_id oid; + hashcpy(oid.hash, info-objectname); + show_tag_lines(oid, lines); + } putchar('\n'); } diff --git a/ref-filter.h b/ref-filter.h index dd28d17..6b6fb96 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -55,6 +55,7 @@ struct ref_filter { struct commit *merge_commit; unsigned int with_commit_tag_algo: 1; + unsigned int lines; }; struct ref_filter_cbdata { @@ -87,7 +88,7 @@ int verify_ref_format(const char *format); /* Sort the given ref_array as per the ref_sorting provided */ void ref_array_sort(struct ref_sorting *sort, struct ref_array *array); /* Print the ref using the given format and quote_style */ -void show_ref_array_item(struct ref_array_item *info, const char *format, int quote_style); +void show_ref_array_item(struct ref_array_item *info, const char *format, int quote_style, unsigned int lines); /* Callback function for parsing the sort option */ int parse_opt_ref_sorting(const struct option *opt, const char *arg, int unset); /* Default sort option based on refname */ -- 2.4.4 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: What's cooking in git.git (Jun 2015, #06; Wed, 24)
Johannes Schindelin johannes.schinde...@gmx.de writes: - I *think* that the current `recreate_opt()` is fine, but if it is used more, we will have to quote the arguments to guard against spaces and quotes and whatnot I admit that that was the reaction I had when I saw it for the first time, until I realized how it is used. And this one I have to disagree. recreate-opt is used to munge a single argument, suitable to be placed into argv[] for execv() like thing---there is no need for shell quoting there. It is a job for the caller that gets its result to shell quote if it wants to pass the result to a shell. So I think this is fine as-is. - There is a loop for (; *argv; argv++) argv_array_push(array, *argv); which might want to be written as while (*argv) argv_array_push(array, *(argv)++); Yeah, the latter is certainly more readable, but I agree this is not a showstopper. I'd gladly take an incremental to update it, though ;-) Thanks, both. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH/WIP v3 07/31] am: extract patch, message and authorship with git-mailinfo
On Wed, Jun 24, 2015 at 11:59 PM, Junio C Hamano gits...@pobox.com wrote: Paul Tan pyoka...@gmail.com writes: 3. I'm over-thinking this and you just want the struct strbufs in the struct am_state to be switched to char*s? Yes, everybody interacts with am_state, and these fields are supposed to be constant during the processing of each patch input message; they should be simple strings, not strbufs, to make sure if anybody _does_ muck with them in-place, that would be very visible. The helpers to initialize them are free to use strbuf API to prepare these simple string fields, of course. OK. I've implemented it on my end. (On a somewhat related thought, currently we do write_file() all over the place, which is really ugly. I'm leaning heavily on introducing an am_save() function, for I don't care how it is done but just update the contents of the am state directory so that it matches the contents of the struct am_state. Sure; the scripted Porcelain may have done echo here, echo there instead of concatenate into a $var and then 'echo $var' at end as that is more natural way to program in that environment. You are doing this in C and prepare the thing in-core and write it all at the point to snapshot may well be the more natural way to program. As long as a process that stops in the middle does not leave on-disk state inconsistent, batching would be fine. For example, you may apply and commit two (or more) patches without updating the on-disk state as you do not see need to give control back to the user (i.e. they applied cleanly) and then write out the on-disk state with .next incremented by two (or more) before giving the control back could be a valid optimization (take this example with a grain of salt, though; I haven't thought too deeply about what should happen if you Ctrl-C the process in the middle). Right, I briefly wondered if we could hold off writing the am_state to disk as much as possible, and only write to disk when we are about to terminate. This would involve installing an atexit() and SIGTERM signal handler, but I haven't thought too deeply about that. Anyway, moving all the writing am_state to disk logic to a central function am_save() would be a good immediate step, I think, so I've implemented it on my end. Thanks, Paul -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] apply: fix adding new files on i-t-a entries
Duy Nguyen pclo...@gmail.com writes: I think it's clear that you need to revert that commit. I didn't see this at all when I made the commit. I didn't either, and no other reviewers did. But now we know it was not sufficient, so let's see... Perhaps a good and safe way forward to resurrect what d95d728a wanted to do is to first add an option to tell run_diff_index() and run_diff_files() which behaviour the caller wants to see, add that only to the caller in wt-status.c? Then incrementally pass that option from more callsites that we are absolutely certain that want this different worldview with respect to i-t-a? Agreed. OK. Perhaps then first I should do that revert and we'll incrementally rebuild on top. Thanks. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: several date related issues
On Thu, Jun 25, 2015 at 01:19:01PM +0200, H.Merijn Brand wrote: *** Dates do not respect LC_TIME Right, we use our own routines for formatting the dates, and not strftime. And it probably should stay that way in general, as git's output is often meant to be parsed. That being said, I do not think it would be wrong to have a date-mode that just showed strftime(%c), or some other arbitrary strftime string. You could then set log.date as appropriate for human consumption. *** git log --date-order and --author-date-order do not order by date Correct. The documentation says: --date-order Show no parents before all of its children are shown, but otherwise show commits in the commit timestamp order. In your example, one commit is the parent of the other, so it hits the first part of the sentence, and the dates are never even compared. There is not a simple way to show commits in arbitrary order without respect to parentage. I think you'd have to do something like: git log --format='%at %H' | sort -rn | cut -d' ' -f2 | git log --stdin --no-walk -Peff -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] apply: fix adding new files on i-t-a entries
On Thu, Jun 25, 2015 at 12:05 AM, Junio C Hamano gits...@pobox.com wrote: Internal diff-index --cached is used for another reason you did not mention (and scripted Porcelains literally use that externally for the same reason). When we start a mergy operation, we say it is OK if the working tree has local changes relative to the index, but we require the index does not have any modifications since the HEAD was read. Side note: some codepaths insist that diff-index --cached and diff-files are both clean, so d95d728a is harmless; the former may say clean on i-t-a entries more than before, but the latter will still catch the difference between the index and the working tree and stop the caller from going forward. With d95d728a (diff-lib.c: adjust position of i-t-a entries in diff, 2015-03-16)'s world view, an empty output from diff-index --cached no longer means that. Entries added with any git add -N are not reported, so we would go ahead to record the merge result on top of that half-dirty index. Side note: a merge based on unpack-trees has an extra layer of safety that unpack_trees() does not ignore i-t-a entry as not exist (yet) and notices that the path does exist in the index but not in HEAD. But that just shows that some parts of the world do need to consider that having an i-t-a in the index makes it different from HEAD. If the mergy operation goes without any conflict, the next thing we do typically is to write the index out as a tree (to record in a new commit, etc.) and we are OK only in that particular case, because i-t-a entries are ignored. But what would happen when the mergy operation conflicts? I haven't thought about that fully, but I doubt it is a safe thing to do in general. But that is just one example that there are also other codepaths that do not want to be fooled into thinking that i-t-a entries do not exist in the index at all. I think it's clear that you need to revert that commit. I didn't see this at all when I made the commit. All we learned from the above discussion is that unconditionally declaring that adding i-t-a entries to the index without doing anything else should keep the index compare the same to HEAD. If d95d728a were only about what wt_status.c sees (and gets reported in git status output), which was what the change wanted to address anyway, we didn't have to have this discussion. Without realizing that two kinds of callers want different view out of diff-index --cached and diff-files, we broke half the world by changing the world order unconditionally for everybody, I am afraid. Perhaps a good and safe way forward to resurrect what d95d728a wanted to do is to first add an option to tell run_diff_index() and run_diff_files() which behaviour the caller wants to see, add that only to the caller in wt-status.c? Then incrementally pass that option from more callsites that we are absolutely certain that want this different worldview with respect to i-t-a? Agreed. -- Duy -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/6] refs backend preamble
David Turner dtur...@twopensource.com writes: This set of patches is a preamble to pluggable ref backends. The intent is to use the ref infrastructure for special refs like CHERRY_PICK_HEAD where possible, and to use git plumbing commands to access refs and reflogs instead of directly writing files to the .git directory. This series is on top of pu at 9039c98c. I won't queue this for now but will read and comment. Thanks. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 8/9] tag.c: implement '--format' option
Implement the '--format' option provided by 'ref-filter'. This lets the user list tags as per desired format similar to the implementation in 'git for-each-ref'. Add tests and documentation for the same. Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- Documentation/git-tag.txt | 15 ++- builtin/tag.c | 11 +++ t/t7004-tag.sh| 16 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index 1950d94..16e396c 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] [--sort=key] [pattern...] + [--column[=options] | --no-column] [--sort=key] [--format=format] [pattern...] 'git tag' -v tagname... @@ -156,6 +156,19 @@ This option is only applicable when listing tags without annotation lines. The object that the new tag will refer to, usually a commit. Defaults to HEAD. +format:: + A string that interpolates `%(fieldname)` from the + object pointed at by a ref being shown. If `fieldname` + is prefixed with an asterisk (`*`) and the ref points + at a tag object, the value for the field in the object + tag refers is used. When unspecified, defaults to + `%(objectname) SPC %(objecttype) TAB %(refname)`. + It also interpolates `%%` to `%`, and `%xx` where `xx` + are hex digits interpolates to character with hex code + `xx`; for example `%00` interpolates to `\0` (NUL), + `%09` to `\t` (TAB) and `%0a` to `\n` (LF). + The fields are same as those in `git for-each-ref`. + CONFIGURATION - diff --git a/builtin/tag.c b/builtin/tag.c index d80120e..257526b 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -30,10 +30,9 @@ static const char * const git_tag_usage[] = { static unsigned int colopts; -static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting) +static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, const char *format) { struct ref_array array; - char *format; int i; memset(array, 0, sizeof(array)); @@ -43,7 +42,7 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting) if (filter-lines) format = %(refname:lalign16); - else + else if (!format) format = %(refname:short); verify_ref_format(format); @@ -324,6 +323,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) struct strbuf err = STRBUF_INIT; struct ref_filter filter; static struct ref_sorting *sorting = NULL, **sorting_tail = sorting; + const char *format = NULL; struct option options[] = { OPT_CMDMODE('l', list, cmdmode, N_(list tag names), 'l'), { OPTION_INTEGER, 'n', NULL, filter.lines, N_(n), @@ -355,6 +355,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) OPTION_CALLBACK, 0, points-at, filter.points_at, N_(object), N_(print only tags of the object), 0, parse_opt_object_name }, + OPT_STRING( 0 , format, format, N_(format), N_(format to use for the output)), OPT_END() }; @@ -394,8 +395,10 @@ int cmd_tag(int argc, const char **argv, const char *prefix) copts.padding = 2; run_column_filter(colopts, copts); } + if (format (filter.lines != -1)) + die(_(--format and -n are incompatible)); filter.name_patterns = argv; - ret = list_tags(filter, sorting); + ret = list_tags(filter, sorting, format); if (column_active(colopts)) stop_column_filter(); return ret; diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index 51a233f..e8cebb6 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1507,4 +1507,20 @@ EOF test_cmp expect actual ' +test_expect_success '--format cannot be used with -n' ' + test_must_fail git tag -l -n4 --format=%(refname) +' + +test_expect_success '--format should list tags as per format given' ' + cat expect -\EOF + foo1.10 + foo1.3 + foo1.6 + foo1.6-rc1 + foo1.6-rc2 + EOF + git tag -l --format=%(refname) foo* actual + test_cmp expect actual +' + test_done -- 2.4.4 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: What's cooking in git.git (Jun 2015, #06; Wed, 24)
Hi, On 2015-06-25 03:01, Stefan Beller wrote: * pt/pull-builtin (2015-06-18) 19 commits - pull: remove redirection to git-pull.sh - pull --rebase: error on no merge candidate cases - pull --rebase: exit early when the working directory is dirty - pull: configure --rebase via branch.name.rebase or pull.rebase - pull: teach git pull about --rebase - pull: set reflog message - pull: implement pulling into an unborn branch - pull: fast-forward working tree if head is updated - pull: check if in unresolved merge state - pull: support pull.ff config - pull: error on no merge candidates - pull: pass git-fetch's options to git-fetch - pull: pass git-merge's options to git-merge - pull: pass verbosity, --progress flags to fetch and merge - pull: implement fetch + merge - pull: implement skeletal builtin pull - argv-array: implement argv_array_pushv() - parse-options-cb: implement parse_opt_passthru_argv() - parse-options-cb: implement parse_opt_passthru() Reimplement 'git pull' in C. This is v4 ($gmane/271943). Comments from mentors and others? I think the series is good as is. I just had a fresh look. Some comments: - I *think* that the current `recreate_opt()` is fine, but if it is used more, we will have to quote the arguments to guard against spaces and quotes and whatnot - There is a loop for (; *argv; argv++) argv_array_push(array, *argv); which might want to be written as while (*argv) argv_array_push(array, *(argv)++); to conform better with Git's coding style, but this one is not crucial at all. Having said that, I really think this is impressive work, and not only the outcome. It is a real pleasure to have you, Paul! I vote for merging, too, Dscho -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 4/9] ref-filter: add support to sort by version
Add support to sort by version using the v:refname and version:refname option. This is achieved by using the 'version_cmp()' function as the comparing function for qsort. Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- ref-filter.c | 20 +--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/ref-filter.c b/ref-filter.c index 57a5cfb..e307fab 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -10,8 +10,9 @@ #include quote.h #include ref-filter.h #include revision.h +#include version.h -typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type; +typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME, FIELD_VER } cmp_type; static struct { const char *name; @@ -53,6 +54,8 @@ static struct { { flag }, { HEAD }, { color }, + { version, FIELD_VER }, + { v, FIELD_VER }, }; /* @@ -629,7 +632,9 @@ static void populate_value(struct ref_array_item *ref) name++; } - if (starts_with(name, refname)) + if (starts_with(name, refname) || + starts_with(name, version:) || + starts_with(name, v:)) refname = ref-refname; else if (starts_with(name, symref)) refname = ref-symref ? ref-symref : ; @@ -695,7 +700,13 @@ static void populate_value(struct ref_array_item *ref) int num_ours, num_theirs; formatp++; - if (starts_with(formatp, lalign)) { + if (starts_with(name, version) || starts_with(name, v)) { + if (strcmp(formatp, refname)) + die(unknown %.*s format %s, + (int)(formatp - name), name, formatp); + v-s = refname; + continue; + } else if (starts_with(formatp, lalign)) { const char *valp; int val; @@ -1165,6 +1176,9 @@ static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, stru case FIELD_STR: cmp = strcmp(va-s, vb-s); break; + case FIELD_VER: + cmp = versioncmp(va-s, vb-s); + break; default: if (va-ul vb-ul) cmp = -1; -- 2.4.4 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: several date related issues
On Thu, 25 Jun 2015 08:44:45 -0400, Jeff King p...@peff.net wrote: On Thu, Jun 25, 2015 at 01:19:01PM +0200, H.Merijn Brand wrote: *** Dates do not respect LC_TIME Right, we use our own routines for formatting the dates, and not strftime. And it probably should stay that way in general, as git's output is often meant to be parsed. That being said, I do not think it would be wrong to have a date-mode that just showed strftime(%c), or some other arbitrary strftime string. You could then set log.date as appropriate for human consumption. Yes please :) --date=lc --date=lc_time --date=locale all spring to mind as valid options *** git log --date-order and --author-date-order do not order by date Correct. The documentation says: --date-order Show no parents before all of its children are shown, but otherwise show commits in the commit timestamp order. In your example, one commit is the parent of the other, so it hits the first part of the sentence, and the dates are never even compared. That is what I gathered, and concluded that the option name is misleading There is not a simple way to show commits in arbitrary order without respect to parentage. I think you'd have to do something like: git log --format='%at %H' | sort -rn | cut -d' ' -f2 | git log --stdin --no-walk I'd like that as gitk option! -- H.Merijn Brand http://tux.nl Perl Monger http://amsterdam.pm.org/ using perl5.00307 .. 5.21 porting perl5 on HP-UX, AIX, and openSUSE http://mirrors.develooper.com/hpux/http://www.test-smoke.org/ http://qa.perl.org http://www.goldmark.org/jeff/stupid-disclaimers/ pgpecr4JREYxS.pgp Description: OpenPGP digital signature
Re: [PATCH 04/17] Makefile: a dry-run can error out if no perl. Document the issue
Philip Oakley philipoak...@iee.org writes: From: Junio C Hamano gits...@pobox.com I am not sure what this patch is trying to achieve. It was probably a bit of 'don't mess with working code', given that I'd used the NO_PERL solution, rather 'document the issue' Then this part applies, I think. If you are not touching what this Makefile actually does, then I would imagine that you are running the buildsystems code that actually drives 'make -n' with some available solution (perhaps you are running 'make -n NO_PERL=NoThanks' or something like that)? Then instead of a command like this that nobody would read in this file, the same command can instead go there to explain what the workaround (e.g. unusual-looking 'make -n NO_PERL=NoThanks') is doing? Thanks. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: git error in tag ...: unterminated header
Wolfgang Denk w...@denx.de writes: Hm... it seems I cannot even easily delte these tags: - git tag -d LABEL_2006_03_12_0025 Deleted tag 'LABEL_2006_03_12_0025' (was eb394f5) - git fsck --full Checking object directories: 100% (256/256), done. Checking object directories: 100% (256/256), done. This is expected. git tag -d only severed the linkage between tagname LABEL_2006_03_12_0025 and the tag object eb394f5; without repacking and pruning, the object eb394f5 is not removed from your object store. dangling tag eb394f56db3e05d00891d6dc36a00df0025cf255 Now I also have this dangling tag thingy... That also is expected. It now is dangling because it is not reachable from any of your refs. git repack -a -d -f after git tag -d git tag -a would make your repository fsck-clean, but I highly doubt that you would want to recreate your tags right now. If I were you, I'd learn to ignore these 'unterminated header' errors for now and wait to see if Git folks decide that 4d0d8975 (Make sure fsck_commit_buffer() does not run out of the buffer, 2014-09-11) is overzealous and giving an error message where there is no error, in which case future versions of Git will not complain on these objects. It is not too late to do the re-tagging after they decide to keep the current behaviour. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 0/9] port tag.c to use ref-filter library
This is part of the GSoC project to unify the commands `git tag -l`, `git branch -l` and `git for-each-ref`. This is a follow up to http://article.gmane.org/gmane.comp.version-control.git/272641 which is still in the 6th iteration. This ports over tag.c to use ref-filter APIs and adds --format, --sort, --merged and --no-merged options to the same. Documentation/git-tag.txt | 39 ++--- builtin/for-each-ref.c| 3 +- builtin/tag.c | 362 ref-filter.c | 100 ref-filter.h | 7 ++- t/t7004-tag.sh| 51 ++--- 6 files changed, 233 insertions(+), 329 deletions(-) -- Regards, Karthik Nayak -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] introduce preciousObjects repository extension
On Wed, Jun 24, 2015 at 10:15:08AM -0700, Junio C Hamano wrote: I agree that would be better. I originally just blocked all use of git-repack, but at the last minute softened it to just repack -d. I'm not sure if that would actually help anyone in practice. Sure, doing git repack without any options is not destructive, but I wonder if anybody actually does it. Hmph, if you cannot afford to lose objects that are unreachable from your refs (because you know your repository has borrowers) but are suffering from too many packs, wouldn't repack -a be the most natural thing to do? Maybe I am biased, but git gc is not the first thing that comes to my mind in that situation. My assumption was that people fall into one of two categories: - people who just run `git gc` - people who are doing something clever, and will use `git repack` to do a full repack after making sure it is safe to do so. E.g., after clone -s, it might be OK to do: for i in ../*.git; do git fetch $i +refs/*:refs/remotes/$i/* done git -c extensions.preciousObjects=false repack -ad But only the user can make that decision; git does not know whether ../*.git is the complete set of children. Certainly git repack -a is a safe stopgap in the shared-object parent, but eventually you will want to do the clever thing. :) I think it is OK to use this patch as a starting point, and for people to loosen the rules later if there is a combination of repack flags that are safe to run but not covered by the current logic (there is no regression, since preciousObjects is a new extension, and going forward it is OK to allow new safe things to open up workflows, but not the other way around). It may even be that the current patch even allows any sane workflow; I am only claiming that I did not think too hard on it, and tried to err on the side of safety, and allowing the workflow above. -Peff -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[ANNOUNCE] Git v2.5.0-rc0
An early preview release Git v2.5.0-rc0 is now available for testing at the usual places. It is comprised of 492 non-merge commits since v2.4.0, contributed by 54 people, 17 of which are new faces. The tarballs are found at: https://www.kernel.org/pub/software/scm/git/testing/ The following public repositories all have a copy of the 'v2.5.0-rc0' tag and the 'master' branch that the tag points at: url = https://kernel.googlesource.com/pub/scm/git/git url = git://repo.or.cz/alt-git.git url = https://code.google.com/p/git-core/ url = git://git.sourceforge.jp/gitroot/git-core/git.git url = git://git-core.git.sourceforge.net/gitroot/git-core/git-core url = https://github.com/gitster/git New contributors whose contributions weren't in v2.4.0 are as follows. Welcome to the Git development community! Allen Hubbe, Ariel Faigon, Blair Holloway, Christian Neukirchen, Danny Lin, Frans Klaver, Fredrik Medley, Lars Kellogg-Stedman, Lex Spoon, Luke Mewburn, Miguel Torroja, Ossi Herrala, Panagiotis Astithas, Quentin Neill, Remi Lespinet, Sébastien Guimmara, and Thomas Schneider. Returning contributors who helped this release are as follows. Thanks for your continued support. Alex Henrie, brian m. carlson, Carlos Martín Nieto, Charles Bailey, David Aguilar, David Turner, Dennis Kaarsemaker, Elia Pinto, Eric Sunshine, Fredrik Gustafsson, Jean-Noel Avila, Jeff King, Jim Hill, Johannes Sixt, Jonathan Nieder, Junio C Hamano, Karthik Nayak, Luke Diamand, Matthieu Moy, Max Kirillov, Michael Coleman, Michael Haggerty, Michael J Gruber, Mike Hommey, Nguyễn Thái Ngọc Duy, Patrick Steinhardt, Paul Tan, Phil Hord, Phillip Sz, Ramsay Allan Jones, René Scharfe, Stefan Beller, SZEDER Gábor, Thomas Braun, Thomas Gummerer, Torsten Bögershausen, and Vitor Antunes. Git 2.5 Release Notes (draft) = Updates since v2.4 -- UI, Workflows Features * The bash completion script (in contrib/) learned a few options that git revert takes. * Whitespace breakages in deleted and context lines can also be painted in the output of git diff and friends with the new --ws-error-highlight option. * List of commands shown by git help are grouped along the workflow elements to help early learners. * git p4 now detects the filetype (e.g. binary) correctly even when the files are opened exclusively. * git p4 attempts to better handle branches in Perforce. * git p4 learned --changes-block-size n to read the changes in chunks from Perforce, instead of making one call to p4 changes that may trigger too many rows scanned error from Perforce. * More workaround for Perforce's row number limit in git p4. * Unlike $EDITOR and $GIT_EDITOR that can hold the path to the command and initial options (e.g. /path/to/emacs -nw), 'git p4' did not let the shell interpolate the contents of the environment variable that name the editor $P4EDITOR (and $EDITOR, too). This release makes it in line with the rest of Git, as well as with Perforce. * A new short-hand branch@{push} denotes the remote-tracking branch that tracks the branch at the remote the branch would be pushed to. * git show-branch --topics HEAD (with no other arguments) did not do anything interesting. Instead, contrast the given revision against all the local branches by default. * A replacement for contrib/workdir/git-new-workdir that does not rely on symbolic links and make sharing of objects and refs safer by making the borrowee and borrowers aware of each other. Consider this as still an experimental feature; the UI will likely to change. * Tweak the sample store backend of the credential helper to honor XDG configuration file locations when specified. * A heuristic we use to catch mistyped paths on the command line git cmd revs pathspec is to make sure that all the non-rev parameters in the later part of the command line are names of the files in the working tree, but that means git grep $str -- \*.c must always be disambiguated with --, because nobody sane will create a file whose name literally is asterisk-dot-see. Loosen the heuristic to declare that with a wildcard string the user likely meant to give us a pathspec. * git merge FETCH_HEAD learned that the previous git fetch could be to create an Octopus merge, i.e. recording multiple branches that are not marked as not-for-merge; this allows us to lose an old style invocation git merge msg HEAD $commits... in the implementation of git pull script; the old style syntax can now be deprecated (but not removed yet). * Filter scripts were run with SIGPIPE disabled on the Git side, expecting that they may not read what Git feeds them to filter. We however treated a filter that does not read its input fully before exiting as an error. We no longer do and ignore
[ANNOUNCE] Git v2.4.5
The latest maintenance release Git v2.4.5 is now available at the usual places. The tarballs are found at: https://www.kernel.org/pub/software/scm/git/ The following public repositories all have a copy of the 'v2.4.5' tag and the 'maint' branch that the tag points at: url = https://kernel.googlesource.com/pub/scm/git/git url = git://repo.or.cz/alt-git.git url = https://code.google.com/p/git-core/ url = git://git.sourceforge.jp/gitroot/git-core/git.git url = git://git-core.git.sourceforge.net/gitroot/git-core/git-core url = https://github.com/gitster/git Git v2.4.5 Release Notes Fixes since v2.4.4 -- * The setup code used to die when core.bare and core.worktree are set inconsistently, even for commands that do not need working tree. * There was a dead code that used to handle git pull --tags and show special-cased error message, which was made irrelevant when the semantics of the option changed back in Git 1.9 days. * color.diff.plain was a misnomer; give it 'color.diff.context' as a more logical synonym. * The configuration reader/writer uses mmap(2) interface to access the files; when we find a directory, it barfed with Out of memory?. * Recent git prune traverses young unreachable objects to safekeep old objects in the reachability chain from them, which sometimes showed unnecessary error messages that are alarming. * git rebase -i fired post-rewrite hook when it shouldn't (namely, when it was told to stop sequencing with 'exec' insn). Also contains typofixes, documentation updates and trivial code clean-ups. Changes since v2.4.4 are as follows: Jeff King (13): diff: accept color.diff.context as a synonym for plain diff.h: rename DIFF_PLAIN color slot to DIFF_CONTEXT read-cache.c: drop PROT_WRITE from mmap of index config.c: fix mmap leak when writing config config.c: avoid xmmap error messages config.c: rewrite ENODEV into EISDIR when mmap fails Makefile: drop dependency between git-instaweb and gitweb Makefile: avoid timestamp updates to GIT-BUILD-OPTIONS Makefile: silence perl/PM.stamp recipe setup_git_directory: delay core.bare/core.worktree errors add quieter versions of parse_{tree,commit} silence broken link warnings with revs-ignore_missing_links suppress errors on missing UNINTERESTING links Junio C Hamano (3): t5407: use - to align the expected output xmmap(): drop Out of memory? Git 2.4.5 Matthieu Moy (2): rebase -i: demonstrate incorrect behavior of post-rewrite rebase -i: fix post-rewrite hook with failed exec command Paul Tan (1): pull: remove --tags error in no merge candidates case SZEDER Gábor (1): Documentation: include 'merge.branchdesc' for merge and config as well Stefan Beller (1): Documentation/technical/pack-protocol: mention http as possible protocol -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 00/17] Make the msvc-build scripts work again
From: Junio C Hamano gits...@pobox.com Philip Oakley philipoak...@iee.org writes: Hopefully it's not too late in the cycle for a review of this contrib/compat item. Has this been discussed in the Windows land and folks are all happy with this change? If so the only thing we would need review on the main list is the top-level change outside compat/ and contrib/, so it may be possible to sneak it in before -rc1. Yes this had been discussed previously on the MsysGit list, and in the referenced Pull Request [msysgit/#318] https://github.com/msysgit/git/pull/318/files. I had aspirations of a slightly bigger series that would also allow the VS compiled output to be installed but that had stalled, so I cut back to fixing the basic 'make it work' steps. The series has been reordered/rebased, and the recently noticed 05/17 err msg fix added. The one unknown is the last patch [17] for the Windows Safe Exception Handling in that the default acceptability was flipped in VS2013 so that zlib became unacceptable to ceratain OS versions without the addition of that option -SAFESEH:NO, but I haven't been able to test that myself (I don't have a complaining system). Otherwise, no, but we can still polish it during the prerelease freeze and aim to merge it in the first batch after the upcoming release. Philip Oakley (17): .gitignore: improve MSVC ignore patterns .gitignore: ignore library directories created by MSVC VS2008 buildsystem (msvc-build) Vcproj.pm: remove duplicate GUID Makefile: a dry-run can error out if no perl. Document the issue engine.pl: fix error message (lib-link) engine.pl: Avoid complications with perl support engine.pl: Properly accept quoted spaces in filenames engine.pl: Fix i18n -o option in msvc buildsystem generator engine.pl: ignore invalidcontinue.obj which is known to MSVC engine.pl: name the msvc buildsystem's makedry error file engine.pl: delete the captured stderr file if empty engine.pl: add debug line to capture the dry-run engine.pl: provide more debug print statements Vcproj.pm: list git.exe first to be startup project vcbuild/readme: Improve layout and reference msvc-build script msvc-build: add complete Microsoft Visual C compilation script config.mak.uname: add MSVC No_SafeExeceptionHandler option .gitignore| 8 ++- Makefile | 3 ++ compat/vcbuild/README | 27 +++--- compat/vcbuild/scripts/msvc-build | 89 +++ config.mak.uname | 9 contrib/buildsystems/Generators/Vcproj.pm | 34 ++-- contrib/buildsystems/engine.pl| 37 ++--- 7 files changed, 174 insertions(+), 33 deletions(-) create mode 100644 compat/vcbuild/scripts/msvc-build mode change 100755 = 100644 contrib/buildsystems/engine.pl Why? Mistake on/by Windows? - My mistake, I hadn't noticed it had happened. I can search out the change step and re-roll. -- Philip -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: git error in tag ...: unterminated header
Wolfgang Denk w...@denx.de writes: Dear Junio, thanks for the fast replies. In message xmqqegkzzoaz@gitster.dls.corp.google.com you wrote: Question is: how can we fix that? It could be that 4d0d8975 is buggy and barking at a non breakage. If there is no message in the tag, i.e. -- 8 -- object 84ef51a632063e8cb57b2e9a4252497512831ffe type commit tag LABEL_2006_03_12_0025 tagger Wolfgang Denk w...@pollux.denx.de 1142119613 +0100 -- 8 -- It seems recent tools cannot create such tags any more? Yeah, we append an extra blank line after the last header even when there is no message. But I do not think that means what you have above is invalid. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/6] bisect: use refs infrastructure for BISECT_START
On Thu, 2015-06-25 at 09:52 -0700, Junio C Hamano wrote: David Turner dtur...@twopensource.com writes: This ref needs to go through the refs backend, since some code assumes that it can be written and read as a ref. And BISECT_HEAD should no longer be a ref because...? I can't remember now why I did this. I guess we'll find out as we work on the remaining patches. I'll take it out for now. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 4/6] refs: add safe_create_reflog function
David Turner dtur...@twopensource.com writes: Make log_ref_setup private, and add public safe_create_reflog which calls log_ref_setup. In a moment, we will use safe_create_reflog to add reflog creation commands to git-reflog. Signed-off-by: David Turner dtur...@twopensource.com --- builtin/checkout.c | 4 +--- refs.c | 11 +++ refs.h | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index 93f63d3..b793670 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -621,7 +621,6 @@ static void update_refs_for_switch(const struct checkout_opts *opts, if (opts-new_orphan_branch) { if (opts-new_branch_log !log_all_ref_updates) { int temp; - struct strbuf log_file = STRBUF_INIT; int ret; const char *ref_name; struct strbuf err = STRBUF_INIT; @@ -629,9 +628,8 @@ static void update_refs_for_switch(const struct checkout_opts *opts, ref_name = mkpath(refs/heads/%s, opts-new_orphan_branch); temp = log_all_ref_updates; log_all_ref_updates = 1; - ret = log_ref_setup(ref_name, log_file, err); + ret = safe_create_reflog(ref_name, err); log_all_ref_updates = temp; - strbuf_release(log_file); if (ret) { fprintf(stderr, _(Can not do reflog for '%s'. %s\n), opts-new_orphan_branch, err.buf); Yup, much nicer ;-) diff --git a/refs.c b/refs.c index de7b5ef..7b02c45 100644 --- a/refs.c +++ b/refs.c @@ -3171,6 +3171,17 @@ int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf return 0; } + +int safe_create_reflog(const char *refname, struct strbuf *err) +{ + int ret; + struct strbuf sb = STRBUF_INIT; + + ret = log_ref_setup(refname, sb, err); + strbuf_release(sb); + return ret; +} + static int log_ref_write_fd(int fd, const unsigned char *old_sha1, const unsigned char *new_sha1, const char *committer, const char *msg) diff --git a/refs.h b/refs.h index debdefc..2986aac 100644 --- a/refs.h +++ b/refs.h @@ -228,7 +228,7 @@ int pack_refs(unsigned int flags); /* * Setup reflog before using. Fill in err and return -1 on failure. */ -int log_ref_setup(const char *refname, struct strbuf *logfile, struct strbuf *err); +int safe_create_reflog(const char *refname, struct strbuf *err); /** Reads log for the value of ref during at_time. **/ extern int read_ref_at(const char *refname, unsigned int flags, -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 5/6] git-reflog: add create and exists functions
David Turner dtur...@twopensource.com writes: Because...??? These are necessary because ref backends manage reflogs. Because ref backends manage reflogs may be a good explanation to implement something as part of ref API, but it does not explain why that something needs to be implemented in the first place. In a moment, we will use these functions to make git stash work with alternate ref backends. Signed-off-by: David Turner dtur...@twopensource.com --- builtin/reflog.c | 79 +++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/builtin/reflog.c b/builtin/reflog.c index c2eb8ff..a64158d 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -13,6 +13,10 @@ static const char reflog_expire_usage[] = git reflog expire [--expire=time] [--expire-unreachable=time] [--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] [--verbose] [--all] refs...; static const char reflog_delete_usage[] = git reflog delete [--rewrite] [--updateref] [--dry-run | -n] [--verbose] refs...; +static const char reflog_create_usage[] = +git reflog create refs...; It makes sense to take more than one; you may want to prepare more than one, and you would signal error by exiting with a non-zero status if any of them failed. +static const char reflog_exists_usage[] = +git reflog exists refs...; This is iffy, though. git reflog exists foo bar says all of them exist or some of them exist? Why is it more useful to implement all of them exist? Perhaps dropping ... would be simpler to explain and less confusing. @@ -699,12 +703,79 @@ static int cmd_reflog_delete(int argc, const char **argv, const char *prefix) return status; } +static int cmd_reflog_create(int argc, const char **argv, const char *prefix) +{ + int i, status = 0, start = 0; + struct strbuf err = STRBUF_INIT; + + for (i = 1; i argc; i++) { + const char *arg = argv[i]; + if (!strcmp(arg, --)) { + i++; + break; + } + else if (arg[0] == '-') + usage(reflog_create_usage); + else + break; + } + + start = i; + + if (argc - start 1) + return error(Nothing to create?); + + for (i = start ; i argc; i++) { s/start ;/start;/ (everywhere). -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: git error in tag ...: unterminated header
Hi Junio Wolfgang, On 2015-06-25 22:24, Junio C Hamano wrote: Wolfgang Denk w...@denx.de writes: In message xmqqegkzzoaz@gitster.dls.corp.google.com you wrote: Question is: how can we fix that? It could be that 4d0d8975 is buggy and barking at a non breakage. Well, I would like to believe that this commit made our code *safer* by making sure that we would never overrun the buffer. Remember: under certain circumstances, the buffer passed to the fsck machinery is *not* terminated by a NUL. The code I introduced simply verifies that there is an empty line because the fsck code stops there and does not look further. If the buffer does *not* contain an empty line, the fsck code runs the danger of looking beyond the allocated memory because it uses functions that assume NUL-terminated strings, while the buffer passed to the fsck code is a counted string. The quick dirty work-around would be to detect when the buffer does not contain an empty line and to make a NUL-terminated copy in that case. A better solution was outlined by Peff back when I submitted those patches: change all the code paths that read objects and make sure that all of them are terminated by a NUL. AFAIR some code paths did that already, but not all of them. Ciao, Dscho -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/6] cherry-pick: treat CHERRY_PICK_HEAD and REVERT_HEAD as refs
David Turner dtur...@twopensource.com writes: Instead of directly writing to and reading from files in $GIT_DIR, use ref API to interact with CHERRY_PICK_HEAD and REVERT_HEAD. Signed-off-by: David Turner dtur...@twopensource.com --- I may have said this already in the last round, but I cannot shake off the feeling that this patch is doing two completely unrelated things at once. The change to refs.c that introduced the should_autocreate_reflog() helper (which is a good idea even without any other changes in this patch) and then using that to commit_ref_update() does not have anything to do with CHERRY_PICK_HEAD/REVERT_HEAD, does it? * commit_ref_update() gained a new flags parameter, but it does not seem to be used at all. Why? * Why is it a good idea to move the does the log exist or should we auto-create? check from log_ref_setup() to commit_ref_update()? These are not just unexplained, but does not have anything to do with using ref API to write and read CHERRY_PICK_HEAD/REVERT_HEAD. They _might_ be a prerequisite, but it is not clear why. I suspect that you do not have to touch refs.c at all for the purpose of the theme of the patch explained by the Subject line. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: git error in tag ...: unterminated header
Johannes Schindelin johannes.schinde...@gmx.de writes: Hi Junio Wolfgang, On 2015-06-25 22:24, Junio C Hamano wrote: Wolfgang Denk w...@denx.de writes: In message xmqqegkzzoaz@gitster.dls.corp.google.com you wrote: Question is: how can we fix that? It could be that 4d0d8975 is buggy and barking at a non breakage. Well, I would like to believe that this commit made our code *safer* by making sure that we would never overrun the buffer. Remember: under certain circumstances, the buffer passed to the fsck machinery is *not* terminated by a NUL. The code I introduced simply verifies that there is an empty line because the fsck code stops there and does not look further. If the buffer does *not* contain an empty line, the fsck code runs the danger of looking beyond the allocated memory because it uses functions that assume NUL-terminated strings, while the buffer passed to the fsck code is a counted string. The quick dirty work-around would be to detect when the buffer does not contain an empty line and to make a NUL-terminated copy in that case. Yes, I can totally understand its quick-and-dirty-ness would break a valid case where there is no need for a blank after the header. A better solution was outlined by Peff back when I submitted those patches: change all the code paths that read objects and make sure that all of them are terminated by a NUL. AFAIR some code paths did that already, but not all of them. I do not think you necessarily need a NUL. As you said, your input is a counted string, so you know the length of the buffer. And you are verifying line by line. As long as you make sure the buffer ends with \n (instead of saying it has \n\n somewhere), updating the existing code that does if (buffer is not well formed wrt tree) barf; else advance buffer to point at the next line; if (buffer is not well formed wrt parent) barf; ... to do this instead: if (buffer is not well formed wrt tree) barf; else advance buffer to point at the next line; if (buffer is now beyond the end of the original length) barf; /* missing parent */ if (buffer is not well formed wrt parent) barf; ... shouldn't be rocket science, no? -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] commit: add commit.signoff config option
In projects that use Signed-off-by, it's convenient to include that line in the commit message by default. The commit.signoff config option allows to add that line in all commits automatically. Document that this config option can be overriden by using --no-signoff. Signed-off-by: Caio Marcelo de Oliveira Filho cmarc...@gmail.com --- Differences from v1: * Use test_config helper in the test * Add bash completion for commit and config Documentation/config.txt | 6 ++ Documentation/git-commit.txt | 5 + builtin/commit.c | 4 contrib/completion/git-completion.bash | 4 +++- t/t7500-commit.sh | 20 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index 3e37b93..e019f62 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1089,6 +1089,12 @@ commit.gpgSign:: convenient to use an agent to avoid typing your GPG passphrase several times. +commit.signoff:: + + A boolean to enable/disable whether Signed-off-by line by the + committer should be added to all commits at the end of the + commit log messages. Defaults to false. + commit.status:: A boolean to enable/disable inclusion of status information in the commit message template when using an editor to prepare the commit diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 904dafa..7546c7a 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -156,6 +156,11 @@ OPTIONS Add Signed-off-by line by the committer at the end of the commit log message. +--no-signoff:: + Countermand `commit.signoff` configuration, preventing a + Signed-off-by line to be added at the end of the commit log + message. + -n:: --no-verify:: This option bypasses the pre-commit and commit-msg hooks. diff --git a/builtin/commit.c b/builtin/commit.c index 254477f..5cfbe57 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1505,6 +1505,10 @@ static int git_commit_config(const char *k, const char *v, void *cb) sign_commit = git_config_bool(k, v) ? : NULL; return 0; } + if (!strcmp(k, commit.signoff)) { + signoff = git_config_bool(k, v); + return 0; + } status = git_gpg_config(k, v, NULL); if (status) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index c97c648..7a79a89 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1123,7 +1123,8 @@ _git_commit () ;; --*) __gitcomp - --all --author= --signoff --verify --no-verify + --all --author= + --signoff --no-signoff --verify --no-verify --edit --no-edit --amend --include --only --interactive --dry-run --reuse-message= --reedit-message= @@ -2009,6 +2010,7 @@ _git_config () color.status.untracked color.status.updated color.ui + commit.signoff commit.status commit.template core.abbrev diff --git a/t/t7500-commit.sh b/t/t7500-commit.sh index 116885a..949272d 100755 --- a/t/t7500-commit.sh +++ b/t/t7500-commit.sh @@ -179,6 +179,26 @@ test_expect_success '--signoff' ' test_cmp expect output ' +test_expect_success 'commit.signoff config option' ' + test_config commit.signoff true + echo yet another content *narf* foo + echo zort | git commit -F - foo + git cat-file commit HEAD | sed 1,/^\$/d output + test_cmp expect output +' + +cat expect EOF +no signed off by here +EOF + +test_expect_success '--no-signoff' ' + test_config commit.signoff true + echo yet another content *narf* foo + echo no signed off by here | git commit --no-signoff -F - foo + git cat-file commit HEAD | sed 1,/^\$/d output + test_cmp expect output +' + test_expect_success 'commit message from file (1)' ' mkdir subdir echo Log in top directory log -- 2.4.4.489.g5bc41de -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] commit: add commit.signoff config option
In both tests, you should probably use 'test_config' instead of 'git config [...] git config --unset', it takes care of it for you (also should prevent the case where the config is not unset when your test fails in the middle). Posted a v2 with this improvement and the bash completion. Thanks for the review. -- Caio Marcelo de Oliveira Filho -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] commit: add commit.signoff config option
On Thu, Jun 25, 2015 at 5:43 AM, Christian Couder christian.cou...@gmail.com wrote: You can use a commit template. Or you can use the commit-msg hook. For example with commands like: grep ^Signed-off-by: $1 || echo Signed-off-by: $(git config user.name) $(git config user.email) $1 If you have more complex needs, there is also git interpret-trailers (see the examples in the man page). Thanks for the references. I was initially using a commit template to solve the problem. But I've considered that since we already handle Signed-off-by somewhat specially (e.g. commit -s), and how common this case is, it was worth adding a config option. -- Caio Marcelo de Oliveira Filho -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH/WIP v3 04/31] am: implement patch queue mechanism
On Wed, Jun 24, 2015 at 10:59 PM, Johannes Schindelin johannes.schinde...@gmx.de wrote: diff --git a/builtin/am.c b/builtin/am.c index dbc8836..af68c51 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -6,6 +6,158 @@ #include cache.h #include builtin.h #include exec_cmd.h +#include parse-options.h +#include dir.h + +struct am_state { + /* state directory path */ + struct strbuf dir; + + /* current and last patch numbers, 1-indexed */ + int cur; + int last; +}; + +/** + * Initializes am_state with the default values. + */ +static void am_state_init(struct am_state *state) +{ + memset(state, 0, sizeof(*state)); + + strbuf_init(state-dir, 0); +} With strbufs, we use the initializer STRBUF_INIT. How about using #define AM_STATE_INIT { STRBUF_INIT, 0, 0 } here? Later in the patch series am_state_init() will also take into account config settings when filling up the default values. e.g. see patches 25/31[1] or 31/31[2]. I think that is reasonable: the purpose of am_state_init() is to initialize the am_state struct with the default values, and the default values can be set by the user through the config settings. This means, though, that we can't use initializers without introducing global variables. [1] http://thread.gmane.org/gmane.comp.version-control.git/271967/focus=271972 [2] http://thread.gmane.org/gmane.comp.version-control.git/271967/focus=271972 +/** + * Reads the contents of `file`. The third argument can be used to give a hint + * about the file size, to avoid reallocs. Returns number of bytes read on + * success, -1 if the file does not exist. If trim is set, trailing whitespace + * will be removed from the file contents. + */ +static int read_state_file(struct strbuf *sb, const char *file, size_t hint, int trim) +{ + strbuf_reset(sb); + if (strbuf_read_file(sb, file, hint) = 0) { + if (trim) + strbuf_trim(sb); + + return sb-len; + } + + if (errno == ENOENT) + return -1; + + die_errno(_(could not read '%s'), file); +} A couple of thoughts: - why not reuse the strbuf by making it a part of the am_state()? That way, you can allocate, say, 1024 bytes (should be plenty enough for most of our operations) and just reuse them in all of the functions. We will not make any of this multi-threaded anyway, I don't think. But too much usage of this temporary strbuf may lead to a situation where one function calls another, and both functions write to the strbuf and clobber its contents. Besides, if we are talking about read_state_file(), it takes an external strbuf, so it gives the caller the freedom to choose which strbuf it uses (e.g. if it is stack allocated or in the am_state struct). I think it's more flexible this way. - Given that we only read short files all the time, why not skip the hint parameter? Especially if we reuse the strbuf, it should be good enough to allocate a reasonable buffer first and then just assume that we do not have to reallocate it all that often anyway. Doh! Right, the hint parameter is quite useless, since in am_load() we use the same strbuf anyway. (And strbuf_init() can set a hint as well) I've removed it on my side. - Since we only read files from the state directory, why not pass the basename as parameter? That way we can avoid calling `am_path()` explicitly over and over again (and yours truly cannot forget to call `am_path()` in future patches). Makes sense. After all, this function is called read_STATE_file() ;-) - If you agree with these suggestions, the signature would become something like static void read_state_file(struct am_state *state, const char *basename, int trim); So for now, my function signature is static void read_state_file(struct strbuf *sb, const struct am_state *state, const char *basename, int trim); +/** + * Remove the am_state directory. + */ +static void am_destroy(const struct am_state *state) +{ + struct strbuf sb = STRBUF_INIT; + + strbuf_addstr(sb, state-dir.buf); + remove_dir_recursively(sb, 0); + strbuf_release(sb); +} Given that `remove_dir_recursively()` has to reset the strbuf with the directory's path to the original value before it returns (because it recurses into itself, therefore the value *has* to be reset when returning), we can just call remove_dir_recursively(state-dir, 0); and do not need another temporary strbuf. Ah right. Although, state-dir is not an strbuf anymore on my side. As Junio[3] rightfully noted, state-dir is not modified by the am_*() API, so it's been changed to a char*. Which means an strbuf is required to be passed to remove_dir_recursively(); +/** + * Increments the patch pointer, and cleans am_state for the application of the + * next patch. + */ +static void am_next(struct am_state *state) +{ + state-cur++; + write_file(am_path(state, next), 1,
git error in tag ...: unterminated header
Hi all, it turns out that recent versions of git (i. e. git version 2.2.0 or later, resp. anything which includes commit 4d0d8975 Make sure fsck_commit_buffer() does not run out of the buffer) throws errors on our git repository git://git.denx.de/u-boot: - git fsck --full Checking object directories: 100% (256/256), done. error in tag eb394f56db3e05d00891d6dc36a00df0025cf255: unterminated header error in tag 9bf86baaa3b35b25baa2d664e2f7f6cafad689ee: unterminated header error in tag c7071e6d645a8e13adb0d4cea2caad27213fa62f: unterminated header Checking objects: 100% (328644/328644), done. Checking connectivity: 325719, done. Apparently for some reason the tags LABEL_2006_03_12_0025, LABEL_2006_04_18_1106, and LABEL_2006_05_19_1133 are missing newlines, which was undetected so far, but now is raised as an error. Question is: how can we fix that? Is there a tool to auto-repair such kind of errors? If not, would it be be a harmless thing to just delete and recreate the same tags (referring to the same commits)? Or can anybody see any problems tha might be caused by such a tag re-creation? I mean, it is not like a rebase of the repository or something like that? Right? Thanks in advance. Best regards, Wolfgang Denk -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: w...@denx.de Artificial Intelligence is the study of how to make real computers act like the ones in movies. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 04/17] Makefile: a dry-run can error out if no perl. Document the issue
Philip Oakley philipoak...@iee.org writes: A 'make -n' dry-run is used as part of the /compat/vcbuild and /contrib/buildsystems code. The commit ee9be06 (perl: detect new files in MakeMaker builds, 2012-07-27) was not aware of that dry-run usage and thus would not execute the target. Add a comment to the make file stating the issue and the available solutions of either NO_PERL or a '+recipe'. I am not sure what this patch is trying to achieve. If you are not touching what this Makefile actually does, then I would imagine that you are running the buildsystems code that actually drives 'make -n' with some available solution (perhaps you are running 'make -n NO_PERL=NoThanks' or something like that)? Then instead of a command like this that nobody would read in this file, the same command can instead go there to explain what the workaround (e.g. unusual-looking 'make -n NO_PERL=NoThanks') is doing? I suspect you mean by +recipe that you modify this makefile to make such a workaround unnecessary? If that is the case, why isn't such a change actually be done with this commit, instead of a comment? I am not sure what this patch is trying to achieve. Puzzled... Signed-off-by: Philip Oakley philipoak...@iee.org --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 149f1c7..22108bb 100644 --- a/Makefile +++ b/Makefile @@ -1746,6 +1746,9 @@ $(SCRIPT_PERL_GEN): perl/perl.mak perl/perl.mak: perl/PM.stamp +# 'make -n' (dry-run) will not execute this target which creates/updates the PM.stamp file. +# To avoid the error of failing to find the target PM.stamp, either use NO_PERL=1 (YesPlease), +# or add a leading '+' to the recipe '+$(QUIET_GEN)$(FIND) perl ...' so that it is executed. perl/PM.stamp: FORCE @$(FIND) perl -type f -name '*.pm' | sort $@+ \ { cmp $@+ $@ /dev/null 2/dev/null || mv $@+ $@; } \ -- 2.3.1 -- -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] commit: add commit.signoff config option
On 25/06, Junio C Hamano wrote: Caio Marcelo de Oliveira Filho cmarc...@gmail.com writes: Hmm, I do not recall seeing v1 but that is OK. The following immediately comes to mind. http://thread.gmane.org/gmane.comp.version-control.git/51754/focus=51780 To be honest I'm not sure I buy that since we have `git commit -s`, which is just as easily added as a really simple git alias. -- Sincerely, Johannes Löthberg PGP Key ID: 0x50FB9B273A9D0BB5 https://theos.kyriasis.com/~kyrias/ signature.asc Description: PGP signature
Re: [PATCH 00/17] Make the msvc-build scripts work again
Philip Oakley philipoak...@iee.org writes: Hopefully it's not too late in the cycle for a review of this contrib/compat item. Has this been discussed in the Windows land and folks are all happy with this change? If so the only thing we would need review on the main list is the top-level change outside compat/ and contrib/, so it may be possible to sneak it in before -rc1. Otherwise, no, but we can still polish it during the prerelease freeze and aim to merge it in the first batch after the upcoming release. Philip Oakley (17): .gitignore: improve MSVC ignore patterns .gitignore: ignore library directories created by MSVC VS2008 buildsystem (msvc-build) Vcproj.pm: remove duplicate GUID Makefile: a dry-run can error out if no perl. Document the issue engine.pl: fix error message (lib-link) engine.pl: Avoid complications with perl support engine.pl: Properly accept quoted spaces in filenames engine.pl: Fix i18n -o option in msvc buildsystem generator engine.pl: ignore invalidcontinue.obj which is known to MSVC engine.pl: name the msvc buildsystem's makedry error file engine.pl: delete the captured stderr file if empty engine.pl: add debug line to capture the dry-run engine.pl: provide more debug print statements Vcproj.pm: list git.exe first to be startup project vcbuild/readme: Improve layout and reference msvc-build script msvc-build: add complete Microsoft Visual C compilation script config.mak.uname: add MSVC No_SafeExeceptionHandler option .gitignore| 8 ++- Makefile | 3 ++ compat/vcbuild/README | 27 +++--- compat/vcbuild/scripts/msvc-build | 89 +++ config.mak.uname | 9 contrib/buildsystems/Generators/Vcproj.pm | 34 ++-- contrib/buildsystems/engine.pl| 37 ++--- 7 files changed, 174 insertions(+), 33 deletions(-) create mode 100644 compat/vcbuild/scripts/msvc-build mode change 100755 = 100644 contrib/buildsystems/engine.pl Why? -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: 'eol' documentation confusion
On 2015-06-22 18.11, Junio C Hamano wrote: Torsten Bögershausen tbo...@web.de writes: eol=lf or eol=crlf are the only useful settings. Everything else is ignored because it does not make sense. See convert.c: static enum eol git_path_check_eol() That makes me wonder... The original reasoning behind the current behaviour that we ignore unknown values given to configuration variables and attributes is so that people can use the same file that has values that are understood by newer versions of Git with older versions of Git. You may be trying the eol=cleverLF setting introduced in Git version 47-prerelease by adding it to .git/info/attributes, and may have found it useful. But you may also have to use the same repository on another machine that you didn't install that future version of Git over the network filesystem. Barfing and not proceeding when we see unknown eol=cleverLF does not sound like a nice thing to do, which is why we just ignore and behave as if the setting was not there. Ideally, however, I think we should ignore an unknown setting as long as it does not matter (i.e. we do not come to the codepath that wants to know eol settings for the path, e.g. running git log to show only the commit log messages and the topology of the history), but we should error out when the unknown setting possibly matters (i.e. we do need the eol setting for the path in order to correctly convert the contents to end-user's liking). Thoughts (and patches ;-)? In short: Good idea, patches follow within the next weeks/months -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Linked workdirs break typo-correction.
This is a weird one.. When standing in a folder inside a linked working copy, the typo-correction breaks all commands. Repro: ~/git $ git --version git version 2.4.4.600.g6397abd ~/git $ git init bar Initialized empty Git repository in ~/git/bar/.git/ ~/git $ cd bar ~/git/bar (master #) $ git commit -m init --allow-empty [master (root-commit) 554ea84] init ~/git/bar (master) $ mkdir folder ~/git/bar (master) $ touch folder/file ~/git/bar (master) $ git add folder ~/git/bar (master +) $ git commit -m folder [master 8c00ba8] folder 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 folder/file ~/git/bar (master) $ cd folder/ ~/git/bar/folder (master) $ git shw WARNING: You called a Git command named 'shw', which does not exist. Continuing under the assumption that you meant 'show' in 0.1 seconds automatically... commit 8c00ba8d30cff0e0d1b9cf110a65ea8f33edf8b2 Author: Bjørnar Snoksrud bsnok...@cisco.com Date: Thu Jun 25 16:08:01 2015 +0200 folder diff --git a/folder/file b/folder/file new file mode 100644 index 000..e69de29 bsnoksru@calculon ~/git/bar/folder (master) $ git branch foo bsnoksru@calculon ~/git/bar/folder (master) $ git checkout foo --to ~/git/foo Enter /home/bsnoksru/git/foo (identifier foo) Switched to branch 'foo' bsnoksru@calculon ~/git/bar/folder (master) $ cd ../../foo/folder/ ~/git/foo/folder (foo) $ git shw WARNING: You called a Git command named 'shw', which does not exist. Continuing under the assumption that you meant 'show' in 0.1 seconds automatically... fatal: internal error: work tree has already been set Current worktree: ~/git/foo New worktree: ~/git/foo/folder ~/git/foo/folder (foo) $ git brnch baz WARNING: You called a Git command named 'brnch', which does not exist. Continuing under the assumption that you meant 'branch' in 0.1 seconds automatically... fatal: internal error: work tree has already been set Current worktree: /home/bsnoksru/git/foo New worktree: /home/bsnoksru/git/foo/folder -- bjor...@snoksrud.no -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 01/17] .gitignore: improve MSVC ignore patterns
Philip Oakley philipoak...@iee.org writes: Add the Microsoft .manifest pattern, and correct the generic 'Debug' and 'Release' directory patterns which were mechanically adjusted way back in c591d5f (gitignore: root most patterns at the top-level directory, 2009-10-26) to allow multi-level projects within the Git suite. Signed-off-by: Philip Oakley philipoak...@iee.org --- .gitignore | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 422c538..55498c1 100644 --- a/.gitignore +++ b/.gitignore @@ -246,5 +246,6 @@ *.user *.idb *.pdb -/Debug/ -/Release/ +*.manifest +**/Debug/ +**/Release/ Why **/ there? Wouldn't *.manifest Debug/ Release/ suffice? -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] commit: add commit.signoff config option
Hi, Hmm, I do not recall seeing v1 but that is OK. http://thread.gmane.org/gmane.comp.version-control.git/272635 http://thread.gmane.org/gmane.comp.version-control.git/272636 The following immediately comes to mind. http://thread.gmane.org/gmane.comp.version-control.git/51754/focus=51780 Thanks for the reference, amazed that I ended up using the same title! From the thread: Even though these lines are not digitally signed, the intent of adding a Signed-off-by: line with your name is that you are certifying its origin, according to the definition of DCO (see Documentation/SubmittingPatches). This should be a conscious act from the signer's part, and making it automatic with a config variable that you set once and forget makes it much less meaningful. This is a fair point. However I've seen that in practice, in some cases it's easier to consider the DCO as the rules for contributing to the entire project. In those cases people tend to use commit templates or aliases or hooks, which in practice automate the signing off act anyway. A similar concern probably applies to format.signOff option. Would be sufficient to add a note about conscious act (like format.signOff has) to the config description? -- Caio Marcelo de Oliveira Filho -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] commit: add commit.signoff config option
Caio Marcelo de Oliveira Filho cmarc...@gmail.com writes: In projects that use Signed-off-by, it's convenient to include that line in the commit message by default. The commit.signoff config option Hmm, I do not recall seeing v1 but that is OK. The following immediately comes to mind. http://thread.gmane.org/gmane.comp.version-control.git/51754/focus=51780 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/3] convert enum date_mode into a struct
On Thu, Jun 25, 2015 at 12:55:02PM -0400, Jeff King wrote: In preparation for adding date modes that may carry extra information beyond the mode itself, this patch converts the date_mode enum into a struct. Most of the conversion is fairly straightforward; we pass the struct as a pointer and dereference the type field where necessary. Locations that declare a date_mode can use a {} constructor. However, the tricky case is where we use the enum labels as constants, like: show_date(t, tz, DATE_NORMAL); Ideally we could say: show_date(t, tz, { DATE_NORMAL }); but of course C does not allow that. Yes it does, e.g. in 6.5.2.5 of C11, example 3 shows: drawline((struct point){.x=1, .y=1}, (struct point){.x=3, .y=4}); The cast is required, but if the argument is pointer-to-const you can construct a temporary in the function call. Of course, whether all of the compilers we target support it is a different question. If they do, perhaps something like: #define SIMPLE_DATE(f) (struct date_mode) { DATE_NORMAL } would allow the callers to remain reasonably sane. Likewise, we cannot cast the constant to a struct, because we need to pass an actual address. Our options are basically: 1. Manually add a struct date_mode d = { DATE_NORMAL } definition to each caller, and pass d. This makes the callers uglier, because they sometimes do not even have their own scope (e.g., they are inside a switch statement). 2. Provide a pre-made global date_normal struct that can be passed by address. We'd also need date_rfc2822, date_iso8601, and so forth. But at least the ugliness is defined in one place. 3. Provide a wrapper that generates the correct struct on the fly. The big downside is that we end up pointing to a single global, which makes our wrapper non-reentrant. But show_date is already not reentrant, so it does not matter. This patch implements 3, along with a minor macro to keep the size of the callers sane. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/6] git-reflog: add create and exists functions
David Turner dtur...@twopensource.com writes: These are necessary because ref backends manage reflogs. Because? Because with core.logAllRefUpdates set to false, creating or updating a ref would not log what is done to it, unless a reflog already exists for the ref. There are cases where we always want to have a reflog for a ref (e.g. refs/stash) regardless of the value of core.logAllRefUpdates, and we need a way to ensure that a reflog for a ref exists. reflog create is the way to do so. Also we need to be able to tell if a reflog for a ref exists, and reflog exists is the way to do so. Now, going back to 4/6, I think create_reflog() function as an external API has a few problems. * Its name does not tell us what should happen when a reflog already exists for the refname the caller asked to create reflog for. I understand that this only makes sure it exists and does not destroy existing one. Its old name, log_ref_setup(), did not have this problem, but now it does. * Its second parameter that is a strbuf is used only internally from within log_ref_write_1(); all the external callers do not look at it and they are forced to strbuf_init() it before calling the function and to strbuf_release() after the function returns. Oh, also 4/6 incorrectly says that log_ref_write() is renamed to create_reflog(), but it was log_ref_setup() that was renamed. I think what 4/6 should have done in order to make the guts of what log_ref_setup() does available as a more useful external API is to * keep log_ref_setup() as-is, make it static to refs.c, and have the internal caller that cares about the strbuf (i.e. the path to the log file) call that; and * Add a thin-wrapper for callers that do not care about the path to the log file, e.g. int vivify_reflog(const char *refname, struct strbuf *err) { int ret; struct strbuf sb = STRBUF_INIT; ret = log_ref_setup(refname, sb, err); strbuf_release(sb); return ret; } Hmm? -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] commit: add commit.signoff config option
Caio Marcelo de Oliveira Filho cmarc...@gmail.com writes: A similar concern probably applies to format.signOff option. Would be sufficient to add a note about conscious act (like format.signOff has) to the config description? I am generally in negative on automating this. This is not just you but makes everybody else's S-o-b less and less meaningful (Their tool have ways to add that string randomly, and many of these ways the user ends up adding that string without even conciously thinking what they are doing. Does that string even mean anything anymore?). One solution might be to make this not a straight-forward boolean, but an option that superficially takes a string and treats one specific value as true and everything else as false, e.g. [commit] signoff = I certify that all my work is licenseable under DCO I dunno. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] convert enum date_mode into a struct
In preparation for adding date modes that may carry extra information beyond the mode itself, this patch converts the date_mode enum into a struct. Most of the conversion is fairly straightforward; we pass the struct as a pointer and dereference the type field where necessary. Locations that declare a date_mode can use a {} constructor. However, the tricky case is where we use the enum labels as constants, like: show_date(t, tz, DATE_NORMAL); Ideally we could say: show_date(t, tz, { DATE_NORMAL }); but of course C does not allow that. Likewise, we cannot cast the constant to a struct, because we need to pass an actual address. Our options are basically: 1. Manually add a struct date_mode d = { DATE_NORMAL } definition to each caller, and pass d. This makes the callers uglier, because they sometimes do not even have their own scope (e.g., they are inside a switch statement). 2. Provide a pre-made global date_normal struct that can be passed by address. We'd also need date_rfc2822, date_iso8601, and so forth. But at least the ugliness is defined in one place. 3. Provide a wrapper that generates the correct struct on the fly. The big downside is that we end up pointing to a single global, which makes our wrapper non-reentrant. But show_date is already not reentrant, so it does not matter. This patch implements 3, along with a minor macro to keep the size of the callers sane. Signed-off-by: Jeff King p...@peff.net --- archive.c | 2 +- builtin/blame.c | 10 +- builtin/commit.c| 4 ++-- builtin/for-each-ref.c | 6 +++--- builtin/log.c | 4 ++-- builtin/shortlog.c | 2 +- builtin/show-branch.c | 3 ++- cache.h | 35 +++ commit.h| 2 +- date.c | 43 +-- fast-import.c | 2 +- http-backend.c | 2 +- log-tree.c | 2 +- pretty.c| 29 +++-- reflog-walk.c | 4 ++-- reflog-walk.h | 4 ++-- refs.c | 4 ++-- revision.c | 4 ++-- revision.h | 2 +- sha1_name.c | 2 +- submodule.c | 2 +- test-date.c | 4 ++-- test-revision-walking.c | 2 +- 23 files changed, 97 insertions(+), 77 deletions(-) diff --git a/archive.c b/archive.c index d37c41d..30bda56 100644 --- a/archive.c +++ b/archive.c @@ -33,7 +33,7 @@ static void format_subst(const struct commit *commit, char *to_free = NULL; struct strbuf fmt = STRBUF_INIT; struct pretty_print_context ctx = {0}; - ctx.date_mode = DATE_NORMAL; + ctx.date_mode.type = DATE_NORMAL; ctx.abbrev = DEFAULT_ABBREV; if (src == buf-buf) diff --git a/builtin/blame.c b/builtin/blame.c index b3e948e..43e8473 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -50,7 +50,7 @@ static int xdl_opts; static int abbrev = -1; static int no_whole_file_rename; -static enum date_mode blame_date_mode = DATE_ISO8601; +static struct date_mode blame_date_mode = { DATE_ISO8601 }; static size_t blame_date_width; static struct string_list mailmap; @@ -1827,7 +1827,7 @@ static const char *format_time(unsigned long time, const char *tz_str, size_t time_width; int tz; tz = atoi(tz_str); - time_str = show_date(time, tz, blame_date_mode); + time_str = show_date(time, tz, blame_date_mode); strbuf_addstr(time_buf, time_str); /* * Add space paddings to time_buf to display a fixed width @@ -2179,7 +2179,7 @@ static int git_blame_config(const char *var, const char *value, void *cb) if (!strcmp(var, blame.date)) { if (!value) return config_error_nonbool(var); - blame_date_mode = parse_date_format(value); + parse_date_format(value, blame_date_mode); return 0; } @@ -2561,13 +2561,13 @@ parse_done: if (cmd_is_annotate) { output_option |= OUTPUT_ANNOTATE_COMPAT; - blame_date_mode = DATE_ISO8601; + blame_date_mode.type = DATE_ISO8601; } else { blame_date_mode = revs.date_mode; } /* The maximum width used to show the dates */ - switch (blame_date_mode) { + switch (blame_date_mode.type) { case DATE_RFC2822: blame_date_width = sizeof(Thu, 19 Oct 2006 16:00:04 -0700); break; diff --git a/builtin/commit.c b/builtin/commit.c index 254477f..7314f33 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -856,7 +856,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, _(%s Date:
[PATCH 3/3] introduce format date-mode
This feeds the format directly to strftime. Besides being a little more flexible, the main advantage is that your system strftime may know more about your locale's preferred format (e.g., how to spell the days of the week). Signed-off-by: Jeff King p...@peff.net --- Documentation/rev-list-options.txt | 5 + builtin/blame.c| 3 +++ cache.h| 2 ++ date.c | 9 - gettext.c | 1 + strbuf.c | 29 + strbuf.h | 5 + t/t6300-for-each-ref.sh| 8 8 files changed, 61 insertions(+), 1 deletion(-) diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index 77ac439..a9b808f 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -727,6 +727,11 @@ format, often found in email messages. + `--date=raw` shows the date in the internal raw Git format `%s %z` format. + +`--date=format:...` feeds the format `...` to your system `strftime`. +Use `--date=format:%c` to show the date in your system locale's +preferred format. See the `strftime` manual for a complete list of +format placeholders. ++ `--date=default` shows timestamps in the original time zone (either committer's or author's). diff --git a/builtin/blame.c b/builtin/blame.c index 43e8473..e2e3e75 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -2596,6 +2596,9 @@ parse_done: case DATE_NORMAL: blame_date_width = sizeof(Thu Oct 19 16:00:04 2006 -0700); break; + case DATE_STRFTIME: + blame_date_width = strlen(show_date(0, 0, blame_date_mode)) + 1; /* add the null */ + break; } blame_date_width -= 1; /* strip the null */ diff --git a/cache.h b/cache.h index 1759011..bb63a58 100644 --- a/cache.h +++ b/cache.h @@ -1105,8 +1105,10 @@ struct date_mode { DATE_ISO8601, DATE_ISO8601_STRICT, DATE_RFC2822, + DATE_STRFTIME, DATE_RAW } type; + const char *strftime_fmt; }; /* diff --git a/date.c b/date.c index cdad4db..8f91569 100644 --- a/date.c +++ b/date.c @@ -163,6 +163,8 @@ void show_date_relative(unsigned long time, int tz, struct date_mode *date_mode_from_type(enum date_mode_type type) { static struct date_mode mode; + if (type == DATE_STRFTIME) + die(BUG: cannot create anonymous strftime date_mode struct); mode.type = type; return mode; } @@ -221,6 +223,8 @@ const char *show_date(unsigned long time, int tz, const struct date_mode *mode) weekday_names[tm-tm_wday], tm-tm_mday, month_names[tm-tm_mon], tm-tm_year + 1900, tm-tm_hour, tm-tm_min, tm-tm_sec, tz); + else if (mode-type == DATE_STRFTIME) + strbuf_addftime(timebuf, mode-strftime_fmt, tm); else strbuf_addf(timebuf, %.3s %.3s %d %02d:%02d:%02d %d%c%+05d, weekday_names[tm-tm_wday], @@ -787,7 +791,10 @@ void parse_date_format(const char *format, struct date_mode *mode) mode-type = DATE_NORMAL; else if (!strcmp(format, raw)) mode-type = DATE_RAW; - else + else if (skip_prefix(format, format:, format)) { + mode-type = DATE_STRFTIME; + mode-strftime_fmt = xstrdup(format); + } else die(unknown date format %s, format); } diff --git a/gettext.c b/gettext.c index 7378ba2..a268a2c 100644 --- a/gettext.c +++ b/gettext.c @@ -162,6 +162,7 @@ void git_setup_gettext(void) podir = GIT_LOCALE_PATH; bindtextdomain(git, podir); setlocale(LC_MESSAGES, ); + setlocale(LC_TIME, ); init_gettext_charset(git); textdomain(git); } diff --git a/strbuf.c b/strbuf.c index 0d4f4e5..a7ba028 100644 --- a/strbuf.c +++ b/strbuf.c @@ -709,3 +709,32 @@ char *xstrfmt(const char *fmt, ...) return ret; } + +void strbuf_addftime(struct strbuf *sb, const char *fmt, const struct tm *tm) +{ + size_t len; + + /* +* strftime reports 0 if it could not fit the result in the buffer. +* Unfortunately, it also reports 0 if the requested time string +* takes 0 bytes. So if we were to probe and grow, we have to choose +* some arbitrary cap beyond which we guess that the format probably +* just results in a 0-length output. Since we have to choose some +* reasonable cap anyway, and since it is not that big, we may +* as well just grow to their in the first place. +*/ + strbuf_grow(sb, 128); + len = strftime(sb-buf + sb-len, sb-alloc - sb-len, fmt, tm); + + if (!len) { + /* +* Either we failed, or the format
Re: [PATCH 2/3] convert enum date_mode into a struct
On Thu, Jun 25, 2015 at 06:03:28PM +0100, John Keeping wrote: Ideally we could say: show_date(t, tz, { DATE_NORMAL }); but of course C does not allow that. Yes it does, e.g. in 6.5.2.5 of C11, example 3 shows: Well, yes. But we generally restrict ourselves to C89 here, so we are not even close. Of course, whether all of the compilers we target support it is a different question. If they do, perhaps something like: #define SIMPLE_DATE(f)(struct date_mode) { DATE_NORMAL } would allow the callers to remain reasonably sane. My patch already introduces DATE_MODE, so you could conditionally hide it there, and fall back to date_mode_from_type when the compiler is too old for this. But then, what is the advantage over the existing solution? It's reentrant, but I don't think that is a problem here. And in patch 3, you'll see that I add an extra assertion to date_mode_from_type that this cannot support (to make sure that we do not create a DATE_STRFTIME mode with no matching format string). The syntax above would at least give us NULL for the string, which is better than random garbage, but I think the assert is better still. -Peff -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: git error in tag ...: unterminated header
Wolfgang Denk w...@denx.de writes: Apparently for some reason the tags LABEL_2006_03_12_0025, LABEL_2006_04_18_1106, and LABEL_2006_05_19_1133 are missing newlines, which was undetected so far, but now is raised as an error. Question is: how can we fix that? Is there a tool to auto-repair such kind of errors? If not, would it be be a harmless thing to just delete and recreate the same tags (referring to the same commits)? Or can anybody see any problems tha might be caused by such a tag re-creation? I mean, it is not like a rebase of the repository or something like that? Right? I am inclined to say that these messages are that recent Git barking at a non-errors, and hopefully there is nothing other than ignoring them you have to do until it gets fixed. But if you decide to recreate tags, there are a few things to keep in mind: * You would get a different object name, of course. You would likely to get different timestamps (you can export the desired timestamp in GIT_COMMITTER_DATE, though). * Those who fetched from you and already have these tags will not get the updated one by default. They need to force fetch them. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] commit: add commit.signoff config option
On 2015-06-25 16.50, Caio Marcelo de Oliveira Filho wrote: +test_expect_success 'commit.signoff config option' ' + test_config commit.signoff true + echo yet another content *narf* foo Minor nit: The or should be written without a space, like this: foo -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] show-branch: use DATE_RELATIVE instead of magic number
This is more readable, and won't break if we ever change the order of the date_mode enum. Signed-off-by: Jeff King p...@peff.net --- builtin/show-branch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/show-branch.c b/builtin/show-branch.c index 323f857..d784613 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -784,7 +784,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix) else msg++; reflog_msg[i] = xstrfmt((%s) %s, - show_date(timestamp, tz, 1), + show_date(timestamp, tz, DATE_RELATIVE), msg); free(logmsg); sprintf(nth_desc, %s@{%d}, *av, base+i); -- 2.4.4.742.g862750c -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/6] refs: replace log_ref_write with create_reflog
David Turner dtur...@twopensource.com writes: In a moment, we will use this to add reflog creation commands to git-reflog. Signed-off-by: David Turner dtur...@twopensource.com --- The title is misleading, if this is merely renaming. I first thought with this change the current callers of log_ref_setup() would get a different/updated behaviour from the API by calling something else, but that is not the case. builtin/checkout.c | 2 +- refs.c | 4 ++-- refs.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index ac4d10a..7549ae2 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -629,7 +629,7 @@ static void update_refs_for_switch(const struct checkout_opts *opts, ref_name = mkpath(refs/heads/%s, opts-new_orphan_branch); temp = log_all_ref_updates; log_all_ref_updates = 1; - ret = log_ref_setup(ref_name, log_file, err); + ret = create_reflog(ref_name, log_file, err); log_all_ref_updates = temp; strbuf_release(log_file); if (ret) { diff --git a/refs.c b/refs.c index c1a563f..93412ee 100644 --- a/refs.c +++ b/refs.c @@ -3119,7 +3119,7 @@ static int copy_msg(char *buf, const char *msg) } /* This function will fill in *err and return -1 on failure */ -int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf *err) +int create_reflog(const char *refname, struct strbuf *sb_logfile, struct strbuf *err) { int logfd, oflags = O_APPEND | O_WRONLY; char *logfile; @@ -3203,7 +3203,7 @@ static int log_ref_write_1(const char *refname, const unsigned char *old_sha1, if (log_all_ref_updates 0) log_all_ref_updates = !is_bare_repository(); - result = log_ref_setup(refname, sb_log_file, err); + result = create_reflog(refname, sb_log_file, err); if (result) return result; diff --git a/refs.h b/refs.h index eee99f6..d4f75a9 100644 --- a/refs.h +++ b/refs.h @@ -233,7 +233,7 @@ int pack_refs(unsigned int flags); /* * Setup reflog before using. Fill in err and return -1 on failure. */ -int log_ref_setup(const char *refname, struct strbuf *logfile, struct strbuf *err); +int create_reflog(const char *refname, struct strbuf *logfile, struct strbuf *err); /** Reads log for the value of ref during at_time. **/ extern int read_ref_at(const char *refname, unsigned int flags, -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: git error in tag ...: unterminated header
Wolfgang Denk w...@denx.de writes: it turns out that recent versions of git (i. e. git version 2.2.0 or later, resp. anything which includes commit 4d0d8975 Make sure fsck_commit_buffer() does not run out of the buffer) throws errors on our git repository git://git.denx.de/u-boot: - git fsck --full Checking object directories: 100% (256/256), done. error in tag eb394f56db3e05d00891d6dc36a00df0025cf255: unterminated header error in tag 9bf86baaa3b35b25baa2d664e2f7f6cafad689ee: unterminated header error in tag c7071e6d645a8e13adb0d4cea2caad27213fa62f: unterminated header Checking objects: 100% (328644/328644), done. Checking connectivity: 325719, done. Apparently for some reason the tags LABEL_2006_03_12_0025, LABEL_2006_04_18_1106, and LABEL_2006_05_19_1133 are missing newlines, which was undetected so far, but now is raised as an error. Question is: how can we fix that? It could be that 4d0d8975 is buggy and barking at a non breakage. If there is no message in the tag, i.e. -- 8 -- object 84ef51a632063e8cb57b2e9a4252497512831ffe type commit tag LABEL_2006_03_12_0025 tagger Wolfgang Denk w...@pollux.denx.de 1142119613 +0100 -- 8 -- I do not offhand see why we want to require that there is a lone blank line at the end. Dscho? What do you think? -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/6] refs.c: add an err argument to log_ref_setup
David Turner dtur...@twopensource.com writes: Add err argument to log_ref_setup that can explain the reason for a failure. This then eliminates the need to manage errno through this function since we can just add strerror(errno) to the err string when meaningful. No callers relied on errno from this function for anything else than the error message. I think I saw Michael did something similar to other codepaths in the ref API recently, and going in the same direction is generally a good thing to do for consistency ;-) write_ref_to_lockfile is a private function that calls log_ref_setup. Update this function to also take an err argument and fill it in. This again eliminates the need to manage errno in this function. This particular patch is not just about log_ref_setup() and its private friend write_ref_to_lockfile(), right? It seems to also touch commit_ref_update(), log_ref_write(), etc. The overall theme of this change is to teach parts of the ref API that deal with writing reflogs to report errors the same way (i.e. as the remainder of the ref API does by using err), and that may be a good single-line summary of the change (aka Subject). if (ret) { - fprintf(stderr, _(Can not do reflog for '%s'\n), - opts-new_orphan_branch); + fprintf(stderr, _(Can not do reflog for '%s'. %s\n), + opts-new_orphan_branch, err.buf); Original is underindented but this makes it even worse. Push continuation line further to the right (or restructure the code so that it does not have to indent too deeply in the first place). Other than that, this step looks sensible. Thanks. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/6] cherry-pick: Use refs infrastructure for CHERRY_PICK_HEAD
David Turner dtur...@twopensource.com writes: Subject: Re: [PATCH 2/6] cherry-pick: Use refs infrastructure for CHERRY_PICK_HEAD Also use refs infrastructure for REVERT_HEAD. These refs need to go through the refs backend, since some code assumes that they can be read as refs. cherry-pick: treat CHERRY_PICK_HEAD and REVERT_HEAD as refs Instead of directly writing to and reading from files in $GIT_DIR, use ref API to interact with CHERRY_PICK_HEAD and REVERT_HEAD. void remove_branch_state(void) { - unlink(git_path(CHERRY_PICK_HEAD)); - unlink(git_path(REVERT_HEAD)); + delete_ref(CHERRY_PICK_HEAD, NULL, REF_NODEREF | REF_NO_REFLOG); + delete_ref(REVERT_HEAD, NULL, REF_NODEREF | REF_NO_REFLOG); Interesting. There is a separate question about NO_REFLOG I'll discuss in more detail later. But no-deref puzzled me. They should not be symbolic, but if somebody by mistake made a symbolic one, we won't accidentally remove another unrelated one through them, so that bit is a good thing to have. static void determine_whence(struct wt_status *s) { + unsigned char unused[20]; if (file_exists(git_path(MERGE_HEAD))) whence = FROM_MERGE; - else if (file_exists(git_path(CHERRY_PICK_HEAD))) { + else if (!read_ref(CHERRY_PICK_HEAD, unused)) { I would have expected that you would use ref_exists() here. diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index 366f0bc..5e27a34 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -415,9 +415,9 @@ __git_ps1 () fi elif [ -f $g/MERGE_HEAD ]; then r=|MERGING - elif [ -f $g/CHERRY_PICK_HEAD ]; then + elif git rev-parse --quiet --verify CHERRY_PICK_HEAD /dev/null; then r=|CHERRY-PICKING - elif [ -f $g/REVERT_HEAD ]; then + elif git rev-parse --quiet --verify REVERT_HEAD /dev/null; then r=|REVERTING Functionality-wise this may be OK but at some point we might want to have a native way to produce $r with a single execution of a binary. @@ -429,8 +429,9 @@ __git_ps1 () # symlink symbolic ref b=$(git symbolic-ref HEAD 2/dev/null) else - local head= - if ! __git_eread $g/HEAD head; then + local head + head=ref: $(git symbolic-ref HEAD 2/dev/null) || head=$(git rev-parse HEAD) + if [ -z $head ]; then This is questionable; before the pre-context of this hunk is a check for HEAD inside $GIT_DIR on the filesystem. Besides, the theme of this patch is about CHERRY_PICK_HEAD and REVERT_HEAD; it does not justify to touch things that deal with HEAD in the same patch. diff --git a/refs.c b/refs.c index b34a54a..c1a563f 100644 --- a/refs.c +++ b/refs.c @@ -2979,7 +2979,7 @@ 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, const unsigned char *sha1, const char *logmsg, - struct strbuf *err); + struct strbuf *err, int flags); int rename_ref(const char *oldrefname, const char *newrefname, const char *logmsg) { @@ -3041,7 +3041,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(lock, orig_sha1, logmsg, err, 0)) { error(unable to write current sha1 into %s: %s, newrefname, err.buf); strbuf_release(err); goto rollback; @@ -3060,7 +3060,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(lock, orig_sha1, NULL, err, 0)) { error(unable to write current sha1 into %s: %s, oldrefname, err.buf); strbuf_release(err); } @@ -3291,12 +3291,13 @@ static int write_ref_to_lockfile(struct ref_lock *lock, */ static int commit_ref_update(struct ref_lock *lock, const unsigned char *sha1, const char *logmsg, - struct strbuf *err) + struct strbuf *err, int flags) { clear_loose_ref_cache(ref_cache); - if (log_ref_write(lock-ref_name, lock-old_oid.hash, sha1, logmsg, err) 0 || - (strcmp(lock-ref_name,
Re: What's cooking in git.git (Jun 2015, #06; Wed, 24)
Hi Junio, On 2015-06-25 15:14, Junio C Hamano wrote: Johannes Schindelin johannes.schinde...@gmx.de writes: - I *think* that the current `recreate_opt()` is fine, but if it is used more, we will have to quote the arguments to guard against spaces and quotes and whatnot I admit that that was the reaction I had when I saw it for the first time, until I realized how it is used. And this one I have to disagree. recreate-opt is used to munge a single argument, suitable to be placed into argv[] for execv() like thing---there is no need for shell quoting there. It is a job for the caller that gets its result to shell quote if it wants to pass the result to a shell. Ah yes, no single command-line is constructed from those reconstructed options. So yes, you're right, all is good! Ciao, Dscho -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v9 0/5] bisect terms
This version takes into account Junio's remark on the previous series, and I did a much more thourough review of the whole, which led to a few fixes (one forgotten strcmp(..., bad) in addition to the other noted by Junio), some style fixes, and some simplifications (the file TERMS_DEFINED of PATCH 5 is gone, it was redundant with BISECT_TERMS in all cases I could think of). Hopefully, patches 1-4 are actually ready to be merged. I'm hesitant about patch 5: I actually ended up spending some time reviewing it and simplifying it, and I'm tempted to consider it as finished. But it probably lacks more tests and review. diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt index a37336e..e783f87 100644 --- a/Documentation/git-bisect.txt +++ b/Documentation/git-bisect.txt @@ -140,16 +140,21 @@ If the builtins terms bad/good and new/old do not satisfy you, you can set your own terms. -git bisect terms term1 term2 +git bisect terms term-new term-old -This command has to be used before a bisection has started. -The term1 must be associated with the latest revisions and term2 with the -ancestors of term1. - -Only the first bisection following the 'git bisect terms' will use the terms. -If you mistyped one of the terms you can do again 'git bisect terms term1 -term2'. +This command has to be used before a bisection has started. term-old +must be associated with the latest revisions and term-new with the +ancestors of term-old. For example, if something was buggy in the +old part of the history, you know somewhere the bug was fixed, and you +want to find the exact commit that fixed it, you may want to say `git +bisect terms fixed broken`; this way, you would mark a commit that +still has the bug with `broken`, and a newer one after the fix with +`fixed`. + +Only the first bisection following the `git bisect terms` will use the +terms. If you mistyped one of the terms you can do again `git bisect +terms term-old term-new`. Bisect visualize diff --git a/bisect.c b/bisect.c index ab09650..d447b65 100644 --- a/bisect.c +++ b/bisect.c @@ -741,21 +741,21 @@ static void handle_bad_merge_base(void) if (is_expected_rev(current_bad_oid)) { char *bad_hex = oid_to_hex(current_bad_oid); char *good_hex = join_sha1_array_hex(good_revs, ' '); - if (!strcmp(name_bad, bad)) { + if (!strcmp(name_bad, bad) !strcmp(name_good, good)) { fprintf(stderr, The merge base %s is bad.\n This means the bug has been fixed between %s and [%s].\n, bad_hex, bad_hex, good_hex); - } else if (!strcmp(name_bad, new)) { + } else if (!strcmp(name_bad, new) !strcmp(name_good, old)) { fprintf(stderr, The merge base %s is new.\n The property has changed between %s and [%s].\n, bad_hex, bad_hex, good_hex); } else { fprintf(stderr, The merge base %s is %s.\n - This means the first commit marked %s is + This means the first '%s' commit is between %s and [%s].\n, - bad_hex, name_bad, name_bad, bad_hex, good_hex); + bad_hex, name_bad, name_good, bad_hex, good_hex); } exit(3); } diff --git a/git-bisect.sh b/git-bisect.sh old mode 100644 new mode 100755 index 8ef2b94..8fee712 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -11,8 +11,8 @@ git bisect (bad|new) [rev] git bisect (good|old) [rev...] mark rev... known-good revisions/ revisions before change in a given property. -git bisect terms term1 term2 - set up term1 and term2 as bisection terms. +git bisect terms term-new term-old + set up term-new and term-old as terms (default: bad, good) git bisect skip [(rev|range)...] mark rev... untestable revisions. git bisect next @@ -81,15 +81,15 @@ bisect_start() { orig_args=$(git rev-parse --sq-quote $@) bad_seen=0 eval='' - # revision_seen is true if a git bisect start - # has revision as arguments - revision_seen=0 - # terms_defined is used to detect if the user - # defined his own terms with git bisect terms - terms_defined=0 - if test -s $GIT_DIR/TERMS_DEFINED + must_write_terms=0 + must_log_terms=0 + if test -s $GIT_DIR/BISECT_TERMS then - terms_defined=1 + # We're going to restart from a clean state and the + # file will be deleted. Record the old state in + # variables and restore it
[PATCH v9 1/5] bisect: correction of typo
From: Antoine Delaite antoine.dela...@ensimag.grenoble-inp.fr Signed-off-by: Antoine Delaite antoine.dela...@ensimag.grenoble-inp.fr Signed-off-by: Matthieu Moy matthieu@imag.fr --- bisect.c| 2 +- t/t6030-bisect-porcelain.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bisect.c b/bisect.c index 03d5cd9..5b8357d 100644 --- a/bisect.c +++ b/bisect.c @@ -743,7 +743,7 @@ static void handle_bad_merge_base(void) fprintf(stderr, Some good revs are not ancestor of the bad rev.\n git bisect cannot work properly in this case.\n - Maybe you mistake good and bad revs?\n); + Maybe you mistook good and bad revs?\n); exit(1); } diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index 06b4868..9e2c203 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -362,7 +362,7 @@ test_expect_success 'bisect starting with a detached HEAD' ' test_expect_success 'bisect errors out if bad and good are mistaken' ' git bisect reset test_must_fail git bisect start $HASH2 $HASH4 2 rev_list_error - grep mistake good and bad rev_list_error + grep mistook good and bad rev_list_error git bisect reset ' -- 2.4.4.414.g318df7a.dirty -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v9 4/5] bisect: add the terms old/new
From: Antoine Delaite antoine.dela...@ensimag.grenoble-inp.fr When not looking for a regression during a bisect but for a fix or a change in another given property, it can be confusing to use 'good' and 'bad'. This patch introduce `git bisect new` and `git bisect old` as an alternative to 'bad' and good': the commits which have a certain property must be marked as `new` and the ones which do not as `old`. The output will be the first commit after the change in the property. During a new/old bisect session you cannot use bad/good commands and vice-versa. Some commands are still not available for old/new: * git rev-list --bisect does not treat the revs/bisect/new and revs/bisect/old-SHA1 files. Old discussions: - http://thread.gmane.org/gmane.comp.version-control.git/86063 introduced bisect fix unfixed to find fix. - http://thread.gmane.org/gmane.comp.version-control.git/182398 discussion around bisect yes/no or old/new. - http://thread.gmane.org/gmane.comp.version-control.git/199758 last discussion and reviews New discussions: - http://thread.gmane.org/gmane.comp.version-control.git/271320 ( v2 1/7-4/7 ) - http://comments.gmane.org/gmane.comp.version-control.git/271343 ( v2 5/7-7/7 ) Signed-off-by: Antoine Delaite antoine.dela...@ensimag.grenoble-inp.fr Signed-off-by: Louis Stuber stub...@ensimag.grenoble-inp.fr Signed-off-by: Valentin Duperray valentin.duper...@ensimag.imag.fr Signed-off-by: Franck Jonas franck.jo...@ensimag.imag.fr Signed-off-by: Lucien Kong lucien.k...@ensimag.imag.fr Signed-off-by: Thomas Nguy thomas.n...@ensimag.imag.fr Signed-off-by: Huynh Khoi Nguyen Nguyen huynh-khoi-nguyen.ngu...@ensimag.imag.fr Signed-off-by: Matthieu Moy matthieu@imag.fr --- Documentation/git-bisect.txt | 48 ++-- bisect.c | 11 +++--- git-bisect.sh| 43 +-- t/t6030-bisect-porcelain.sh | 38 +++ 4 files changed, 120 insertions(+), 20 deletions(-) diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt index 4cb52a7..3c3021a 100644 --- a/Documentation/git-bisect.txt +++ b/Documentation/git-bisect.txt @@ -18,8 +18,8 @@ on the subcommand: git bisect help git bisect start [--no-checkout] [bad [good...]] [--] [paths...] - git bisect bad [rev] - git bisect good [rev...] + git bisect (bad|new) [rev] + git bisect (good|old) [rev...] git bisect skip [(rev|range)...] git bisect reset [commit] git bisect visualize @@ -104,6 +104,35 @@ For example, `git bisect reset HEAD` will leave you on the current bisection commit and avoid switching commits at all, while `git bisect reset bisect/bad` will check out the first bad revision. + +Alternative terms: bisect new and bisect old + + +If you are not at ease with the terms bad and good, perhaps +because you are looking for the commit that introduced a fix, you can +alternatively use new and old instead. +But note that you cannot mix bad and good with new and old. + + +git bisect new [rev] + + +Marks the commit as new, e.g. the bug is no longer there, if you are looking +for a commit that fixed a bug, or the feature that used to work is now broken +at this point, if you are looking for a commit that introduced a bug. +It is the equivalent of git bisect bad [rev]. + + +git bisect old [rev...] + + +Marks the commit as old, as the opposite of 'git bisect new'. +It is the equivalent of git bisect good [rev...]. + +You must run `git bisect start` without commits as argument and run +`git bisect new rev`/`git bisect old rev...` after to add the +commits. + Bisect visualize @@ -379,6 +408,21 @@ In this case, when 'git bisect run' finishes, bisect/bad will refer to a commit has at least one parent whose reachable graph is fully traversable in the sense required by 'git pack objects'. +* Look for a fix instead of a regression in the code ++ + +$ git bisect start +$ git bisect new HEAD# current commit is marked as new +$ git bisect old HEAD~10 # the tenth commit from now is marked as old + ++ +Let's consider the last commit has a given property, and that we are looking +for the commit which introduced this property. For each commit the bisection +guide us to, we will test if the property is present. If it is we will mark +the commit as new with 'git bisect new', otherwise we will mark it as old. +At the end of the bisect session, the result will be the first new commit (e.g +the first one with the property). + SEE ALSO diff --git a/bisect.c b/bisect.c index
[PATCH v9 2/5] bisect: replace hardcoded bad|good by variables
From: Antoine Delaite antoine.dela...@ensimag.grenoble-inp.fr To add new tags like old/new and have keywords less confusing, the first step is to avoid hardcoding the keywords. The default mode is still bad/good. Signed-off-by: Antoine Delaite antoine.dela...@ensimag.grenoble-inp.fr Signed-off-by: Louis Stuber stub...@ensimag.grenoble-inp.fr Signed-off-by: Valentin Duperray valentin.duper...@ensimag.imag.fr Signed-off-by: Franck Jonas franck.jo...@ensimag.imag.fr Signed-off-by: Lucien Kong lucien.k...@ensimag.imag.fr Signed-off-by: Thomas Nguy thomas.n...@ensimag.imag.fr Signed-off-by: Huynh Khoi Nguyen Nguyen huynh-khoi-nguyen.ngu...@ensimag.imag.fr Signed-off-by: Matthieu Moy matthieu@imag.fr --- bisect.c | 54 +- git-bisect.sh | 57 +++-- 2 files changed, 68 insertions(+), 43 deletions(-) diff --git a/bisect.c b/bisect.c index 5b8357d..9368f6c 100644 --- a/bisect.c +++ b/bisect.c @@ -21,6 +21,9 @@ static const char *argv_checkout[] = {checkout, -q, NULL, --, NULL}; static const char *argv_show_branch[] = {show-branch, NULL, NULL}; static const char *argv_update_ref[] = {update-ref, --no-deref, BISECT_HEAD, NULL, NULL}; +static const char *name_bad; +static const char *name_good; + /* Remember to update object flag allocation in object.h */ #define COUNTED(1u16) @@ -403,15 +406,21 @@ struct commit_list *find_bisection(struct commit_list *list, static int register_ref(const char *refname, const struct object_id *oid, int flags, void *cb_data) { - if (!strcmp(refname, bad)) { + struct strbuf good_prefix = STRBUF_INIT; + strbuf_addstr(good_prefix, name_good); + strbuf_addstr(good_prefix, -); + + if (!strcmp(refname, name_bad)) { current_bad_oid = xmalloc(sizeof(*current_bad_oid)); oidcpy(current_bad_oid, oid); - } else if (starts_with(refname, good-)) { + } else if (starts_with(refname, good_prefix.buf)) { sha1_array_append(good_revs, oid-hash); } else if (starts_with(refname, skip-)) { sha1_array_append(skipped_revs, oid-hash); } + strbuf_release(good_prefix); + return 0; } @@ -634,7 +643,7 @@ static void exit_if_skipped_commits(struct commit_list *tried, return; printf(There are only 'skip'ped commits left to test.\n - The first bad commit could be any of:\n); + The first %s commit could be any of:\n, name_bad); print_commit_list(tried, %s\n, %s\n); if (bad) printf(%s\n, oid_to_hex(bad)); @@ -732,18 +741,24 @@ static void handle_bad_merge_base(void) if (is_expected_rev(current_bad_oid)) { char *bad_hex = oid_to_hex(current_bad_oid); char *good_hex = join_sha1_array_hex(good_revs, ' '); - - fprintf(stderr, The merge base %s is bad.\n - This means the bug has been fixed - between %s and [%s].\n, - bad_hex, bad_hex, good_hex); - + if (!strcmp(name_bad, bad) !strcmp(name_good, good)) { + fprintf(stderr, The merge base %s is bad.\n + This means the bug has been fixed + between %s and [%s].\n, + bad_hex, bad_hex, good_hex); + } else { + fprintf(stderr, The merge base %s is %s.\n + This means the first '%s' commit is + between %s and [%s].\n, + bad_hex, name_bad, name_good, bad_hex, good_hex); + } exit(3); } - fprintf(stderr, Some good revs are not ancestor of the bad rev.\n + fprintf(stderr, Some %s revs are not ancestor of the %s rev.\n git bisect cannot work properly in this case.\n - Maybe you mistook good and bad revs?\n); + Maybe you mistook %s and %s revs?\n, + name_good, name_bad, name_good, name_bad); exit(1); } @@ -755,10 +770,10 @@ static void handle_skipped_merge_base(const unsigned char *mb) warning(the merge base between %s and [%s] must be skipped.\n - So we cannot be sure the first bad commit is + So we cannot be sure the first %s commit is between %s and %s.\n We continue anyway., - bad_hex, good_hex, mb_hex, bad_hex); + bad_hex, good_hex, name_bad, mb_hex, bad_hex); free(good_hex); } @@ -839,7 +854,7 @@ static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout) int fd; if (!current_bad_oid) - die(a bad revision is needed); +
[PATCH v9 3/5] bisect: simplify the addition of new bisect terms
From: Antoine Delaite antoine.dela...@ensimag.grenoble-inp.fr We create a file BISECT_TERMS in the repository .git to be read during a bisection. The fonctions to be changed if we add new terms are quite few. In git-bisect.sh : check_and_set_terms bisect_voc Co-authored-by: Louis Stuber stub...@ensimag.grenoble-inp.fr Tweaked-by: Matthieu Moy matthieu@imag.fr Signed-off-by: Antoine Delaite antoine.dela...@ensimag.grenoble-inp.fr Signed-off-by: Louis Stuber stub...@ensimag.grenoble-inp.fr Signed-off-by: Valentin Duperray valentin.duper...@ensimag.imag.fr Signed-off-by: Franck Jonas franck.jo...@ensimag.imag.fr Signed-off-by: Lucien Kong lucien.k...@ensimag.imag.fr Signed-off-by: Thomas Nguy thomas.n...@ensimag.imag.fr Signed-off-by: Huynh Khoi Nguyen Nguyen huynh-khoi-nguyen.ngu...@ensimag.imag.fr Signed-off-by: Matthieu Moy matthieu@imag.fr --- bisect.c | 33 ++-- git-bisect.sh | 70 +-- revision.c| 20 +++-- 3 files changed, 112 insertions(+), 11 deletions(-) diff --git a/bisect.c b/bisect.c index 9368f6c..c5f96eb 100644 --- a/bisect.c +++ b/bisect.c @@ -905,6 +905,36 @@ static void show_diff_tree(const char *prefix, struct commit *commit) } /* + * The terms used for this bisect session are stored in BISECT_TERMS. + * We read them and store them to adapt the messages accordingly. + * Default is bad/good. + */ +void read_bisect_terms(const char **read_bad, const char **read_good) +{ + struct strbuf str = STRBUF_INIT; + const char *filename = git_path(BISECT_TERMS); + FILE *fp = fopen(filename, r); + + if (!fp) { + if (errno == ENOENT) { + *read_bad = bad; + *read_good = good; + return; + } else { + die(could not read file '%s': %s, filename, + strerror(errno)); + } + } else { + strbuf_getline(str, fp, '\n'); + *read_bad = strbuf_detach(str, NULL); + strbuf_getline(str, fp, '\n'); + *read_good = strbuf_detach(str, NULL); + } + strbuf_release(str); + fclose(fp); +} + +/* * We use the convention that exiting with an exit code 10 means that * the bisection process finished successfully. * In this case the calling shell script should exit 0. @@ -920,8 +950,7 @@ int bisect_next_all(const char *prefix, int no_checkout) const unsigned char *bisect_rev; char bisect_rev_hex[GIT_SHA1_HEXSZ + 1]; - name_bad = bad; - name_good = good; + read_bisect_terms(name_bad, name_good); if (read_bisect_refs()) die(reading bisect refs failed); diff --git a/git-bisect.sh b/git-bisect.sh index ce6412f..7bb18db 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -77,6 +77,9 @@ bisect_start() { orig_args=$(git rev-parse --sq-quote $@) bad_seen=0 eval='' + # revision_seen is true if a git bisect start + # has revision as arguments + revision_seen=0 if test z$(git rev-parse --is-bare-repository) != zfalse then mode=--no-checkout @@ -101,6 +104,9 @@ bisect_start() { die $(eval_gettext '\$arg' does not appear to be a valid revision) break } + + revision_seen=1 + case $bad_seen in 0) state=$NAME_BAD ; bad_seen=1 ;; *) state=$NAME_GOOD ;; @@ -172,6 +178,11 @@ bisect_start() { } git rev-parse --sq-quote $@ $GIT_DIR/BISECT_NAMES eval $eval true + if test $revision_seen -eq 1 test ! -s $GIT_DIR/BISECT_TERMS + then + echo $NAME_BAD $GIT_DIR/BISECT_TERMS + echo $NAME_GOOD $GIT_DIR/BISECT_TERMS + fi echo git bisect start$orig_args $GIT_DIR/BISECT_LOG || exit # # Check if we can proceed to the next bisect state. @@ -232,6 +243,7 @@ bisect_skip() { bisect_state() { bisect_autostart state=$1 + check_and_set_terms $state case $#,$state in 0,*) die $(gettext Please call 'bisect_state' with at least one argument.) ;; @@ -291,15 +303,17 @@ bisect_next_check() { : bisect without $NAME_GOOD... ;; *) - + bad_syn=$(bisect_voc bad) + good_syn=$(bisect_voc good) if test -s $GIT_DIR/BISECT_START then - gettextln You need to give me at least one good and one bad revision. -(You can use \git bisect bad\ and \git bisect good\ for that.) 2 + + eval_gettextln You need to give me at least one \$bad_syn and one \$good_syn revision. +(You can use \git bisect
[PATCH v9 5/5] bisect: allow any terms set by user
From: Antoine Delaite antoine.dela...@ensimag.grenoble-inp.fr Introduction of the git bisect terms command. The user can set his own terms. It will work exactly like before. The terms must be set before the start. Signed-off-by: Antoine Delaite antoine.dela...@ensimag.grenoble-inp.fr Signed-off-by: Louis Stuber stub...@ensimag.grenoble-inp.fr Signed-off-by: Matthieu Moy matthieu@imag.fr --- Documentation/git-bisect.txt | 24 + git-bisect.sh| 80 ++-- t/t6030-bisect-porcelain.sh | 43 3 files changed, 137 insertions(+), 10 deletions(-) diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt index 3c3021a..e783f87 100644 --- a/Documentation/git-bisect.txt +++ b/Documentation/git-bisect.txt @@ -133,6 +133,30 @@ You must run `git bisect start` without commits as argument and run `git bisect new rev`/`git bisect old rev...` after to add the commits. +Alternative terms: use your own terms +~ + +If the builtins terms bad/good and new/old do not satisfy you, you can +set your own terms. + + +git bisect terms term-new term-old + + +This command has to be used before a bisection has started. term-old +must be associated with the latest revisions and term-new with the +ancestors of term-old. For example, if something was buggy in the +old part of the history, you know somewhere the bug was fixed, and you +want to find the exact commit that fixed it, you may want to say `git +bisect terms fixed broken`; this way, you would mark a commit that +still has the bug with `broken`, and a newer one after the fix with +`fixed`. + +Only the first bisection following the `git bisect terms` will use the +terms. If you mistyped one of the terms you can do again `git bisect +terms term-old term-new`. + + Bisect visualize diff --git a/git-bisect.sh b/git-bisect.sh index 569898b..8fee712 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -1,6 +1,6 @@ #!/bin/sh -USAGE='[help|start|bad|good|new|old|skip|next|reset|visualize|replay|log|run]' +USAGE='[help|start|bad|good|new|old|terms|skip|next|reset|visualize|replay|log|run]' LONG_USAGE='git bisect help print this long help message. git bisect start [--no-checkout] [bad [good...]] [--] [pathspec...] @@ -11,6 +11,8 @@ git bisect (bad|new) [rev] git bisect (good|old) [rev...] mark rev... known-good revisions/ revisions before change in a given property. +git bisect terms term-new term-old + set up term-new and term-old as terms (default: bad, good) git bisect skip [(rev|range)...] mark rev... untestable revisions. git bisect next @@ -80,6 +82,16 @@ bisect_start() { bad_seen=0 eval='' must_write_terms=0 + must_log_terms=0 + if test -s $GIT_DIR/BISECT_TERMS + then + # We're going to restart from a clean state and the + # file will be deleted. Record the old state in + # variables and restore it below. + must_write_terms=1 + must_log_terms=1 + get_terms + fi if test z$(git rev-parse --is-bare-repository) != zfalse then mode=--no-checkout @@ -183,10 +195,14 @@ bisect_start() { } git rev-parse --sq-quote $@ $GIT_DIR/BISECT_NAMES eval $eval true - if test $must_write_terms -eq 1 test ! -s $GIT_DIR/BISECT_TERMS + if test $must_write_terms -eq 1 then - echo $NAME_BAD $GIT_DIR/BISECT_TERMS - echo $NAME_GOOD $GIT_DIR/BISECT_TERMS + write_terms $NAME_BAD $NAME_GOOD + if test $must_log_terms -eq 1 + then + echo git bisect terms $NAME_BAD $NAME_GOOD \ + $GIT_DIR/BISECT_LOG + fi fi echo git bisect start$orig_args $GIT_DIR/BISECT_LOG || exit # @@ -450,6 +466,8 @@ bisect_replay () { eval $cmd ;; $NAME_GOOD|$NAME_BAD|skip) bisect_write $command $rev ;; + terms) + bisect_terms $rev ;; *) die $(gettext ?? what are you talking about?) ;; esac @@ -534,7 +552,8 @@ get_terms () { check_and_set_terms () { cmd=$1 case $cmd in - bad|good|new|old) + skip|start|terms) ;; + *) if test -s $GIT_DIR/BISECT_TERMS test $cmd != $NAME_BAD test $cmd != $NAME_GOOD then die $(eval_gettext Invalid command: you're currently in a \$NAME_BAD/\$NAME_GOOD bisect.) @@ -543,16 +562,14 @@ check_and_set_terms () { bad|good) if ! test -s $GIT_DIR/BISECT_TERMS
Re: [PATCH v2] commit: add commit.signoff config option
Junio C Hamano gits...@pobox.com writes: [commit] signoff = I certify that all my work is licenseable under DCO I like this one. The paranoid version would be signoff = I certify that all my work in /home/my/projects/foo are ... to avoid mistakenly have the config option applied to the wrong repo. But that's probably overkill. -- Matthieu Moy http://www-verimag.imag.fr/~moy/ -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/6] git-reflog: add create and exists functions
Junio C Hamano gits...@pobox.com writes: Now, going back to 4/6, I think create_reflog() function as an external API has a few problems. * Its name does not tell us what should happen when a reflog already exists for the refname the caller asked to create reflog for. I understand that this only makes sure it exists and does not destroy existing one. Its old name, log_ref_setup(), did not have this problem, but now it does. ... * Add a thin-wrapper for callers that do not care about the path to the log file, e.g. int vivify_reflog(const char *refname, struct strbuf *err) { As usual, I am aware that I am not good at naming things (but I can tell when somebody uses a bad name), and vivify may be a horrible name for that. A reroll with a better name is very much welcomed. Perhaps prepare-reflog? I dunno. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 5/5] bisect: allow any terms set by user
Junio C Hamano gits...@pobox.com writes: +Only the first bisection following the `git bisect terms` will use the +terms. If you mistyped one of the terms you can do again `git bisect +terms term-old term-new`. This paragraph may need further polishing. The first sentence makes it sound as if this is a valid sequence, but I do not think that is what you meant: $ git bisect start master maint $ git bisect bad $ git bisect terms new old $ git bisect old $ git bisect bad I think what you wanted to say was that git bisect terms is in effect during the single bisect session, and after you are done with git bisect reset, the next bisect session, unless you use git bisect terms, will use bad and good, as that is the default pair of terms. The second sentence may want to be something like If you mistyped one of the terms, you can do another git bisect terms term-new term-old to correct them, but that is possible only before you start the bisection. Otherwise, you invite this $ git bisect start master maint $ git bisect terms new olf $ git bisect olf $ git bisect new $ git bisect old ... error message that says you can give either new and olf $ git bisect terms new old $ git bisect old which may not work well. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/6] cherry-pick: treat CHERRY_PICK_HEAD and REVERT_HEAD as refs
On Thu, 2015-06-25 at 14:11 -0700, Junio C Hamano wrote: David Turner dtur...@twopensource.com writes: Instead of directly writing to and reading from files in $GIT_DIR, use ref API to interact with CHERRY_PICK_HEAD and REVERT_HEAD. Signed-off-by: David Turner dtur...@twopensource.com --- I may have said this already in the last round, but I cannot shake off the feeling that this patch is doing two completely unrelated things at once. The change to refs.c that introduced the should_autocreate_reflog() helper (which is a good idea even without any other changes in this patch) I'll break that out into a separate patch when I reroll. and then using that to commit_ref_update() does not have anything to do with CHERRY_PICK_HEAD/REVERT_HEAD, does it? I had thought that it did, but some testing shows that it does not (or at least does not yet). The original series of patches was assembled out of a long process of making the test suite pass with the alternate ref backend. I expect that as I rewrite that series, I'll either figure out what issues these change solved, or remove them. In this case, I'll split the patch. * commit_ref_update() gained a new flags parameter, but it does not seem to be used at all. Why? cruft, will remove. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: git error in tag ...: unterminated header
Junio C Hamano gits...@pobox.com writes: Johannes Schindelin johannes.schinde...@gmx.de writes: ... If the buffer does *not* contain an empty line, the fsck code runs the danger of looking beyond the allocated memory because it uses functions that assume NUL-terminated strings, while the buffer passed to the fsck code is a counted string. that already, but not all of them. ... I do not think you necessarily need a NUL. As you said, your input is a counted string, so you know the length of the buffer. And you are verifying line by line. As long as you make sure the buffer ends with \n (instead of saying it has \n\n somewhere), updating the existing code that does ... to do this instead: ... shouldn't be rocket science, no? Here is to illustrate what I meant by the above. I did only the tag side (this is on 'maint'), because I did not want to conflict with a larger change to fsck you have on 'pu'. I made it use an updated version of require_end_of_header(), which I named prescan_headers(), as the new sanity check does not require \n\n as the only end of header, and also the sanity check (both old and new) also checks for NUL. I didn't assess how much more involved to make fsck-commit-buffer to use prescan-headers (and retire require-end-of-header), though. fsck.c | 39 ++- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/fsck.c b/fsck.c index 10bcb65..7d2d07d 100644 --- a/fsck.c +++ b/fsck.c @@ -261,6 +261,29 @@ static int require_end_of_header(const void *data, unsigned long size, return error_func(obj, FSCK_ERROR, unterminated header); } +static int prescan_headers(const void *data, unsigned long size, + struct object *obj, fsck_error error_func) +{ + const char *buffer = (const char *)data; + unsigned long i; + + for (i = 0; i size; i++) { + switch (buffer[i]) { + case '\0': + return error_func(obj, FSCK_ERROR, + unterminated header: NUL at offset %d, i); + case '\n': + if (i + 1 size buffer[i + 1] == '\n') + return 0; /* end of header */ + } + } + + /* no blank (i.e. headers and nothing else */ + if (size buffer[size - 1] == '\n') + return 0; + return error_func(obj, FSCK_ERROR, unterminated header); +} + static int fsck_ident(const char **ident, struct object *obj, fsck_error error_func) { char *end; @@ -365,6 +388,7 @@ static int fsck_tag_buffer(struct tag *tag, const char *data, unsigned char sha1[20]; int ret = 0; const char *buffer; + const char *end_buffer; char *to_free = NULL, *eol; struct strbuf sb = STRBUF_INIT; @@ -387,10 +411,12 @@ static int fsck_tag_buffer(struct tag *tag, const char *data, } } - if (require_end_of_header(buffer, size, tag-object, error_func)) + end_buffer = buffer + size; + if (prescan_headers(buffer, size, tag-object, error_func)) goto done; - if (!skip_prefix(buffer, object , buffer)) { + if (end_buffer = buffer || + !skip_prefix(buffer, object , buffer)) { ret = error_func(tag-object, FSCK_ERROR, invalid format - expected 'object' line); goto done; } @@ -400,7 +426,8 @@ static int fsck_tag_buffer(struct tag *tag, const char *data, } buffer += 41; - if (!skip_prefix(buffer, type , buffer)) { + if (end_buffer = buffer || + !skip_prefix(buffer, type , buffer)) { ret = error_func(tag-object, FSCK_ERROR, invalid format - expected 'type' line); goto done; } @@ -415,7 +442,8 @@ static int fsck_tag_buffer(struct tag *tag, const char *data, goto done; buffer = eol + 1; - if (!skip_prefix(buffer, tag , buffer)) { + if (end_buffer = buffer || + !skip_prefix(buffer, tag , buffer)) { ret = error_func(tag-object, FSCK_ERROR, invalid format - expected 'tag' line); goto done; } @@ -430,7 +458,8 @@ static int fsck_tag_buffer(struct tag *tag, const char *data, (int)(eol - buffer), buffer); buffer = eol + 1; - if (!skip_prefix(buffer, tagger , buffer)) + if (end_buffer = buffer || + !skip_prefix(buffer, tagger , buffer)) /* early tags do not contain 'tagger' lines; warn only */ error_func(tag-object, FSCK_WARN, invalid format - expected 'tagger' line); else -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 04/17] Makefile: a dry-run can error out if no perl. Document the issue
From: Junio C Hamano gits...@pobox.com Philip Oakley philipoak...@iee.org writes: From: Junio C Hamano gits...@pobox.com I am not sure what this patch is trying to achieve. It was probably a bit of 'don't mess with working code', given that I'd used the NO_PERL solution, rather 'document the issue' Then this part applies, I think. If you are not touching what this Makefile actually does, then I would imagine that you are running the buildsystems code that actually drives 'make -n' with some available solution (perhaps you are running 'make -n NO_PERL=NoThanks' or something like that)? Then instead of a command like this that nobody would read in this file, the same command can instead go there to explain what the workaround (e.g. unusual-looking 'make -n NO_PERL=NoThanks') is doing? I was more of the view that this was about prevention (here), rather than retrospective explanation of the code (there). In my case the errors were showing problems with the PM.stamp in the makefile (I didn't have the solution at that point). So either a short comment # consider using 'NO_PERL=YesPlease' for dry run invocations (beware your double negative ;-), or the addition of the '+recipe', would still be my preferred change, rather than leaving the open manhole for others to fall into. The thread on my difficulties is at $gmane/263656 (2015-02-10 22:51) At the moment I'm getting (on my old WinXP machine, using Msysgit 1.9.5 as a basis) $ make -n MSVC=1 V=1 1makedry.txt make[1]: *** No rule to make target `PM.stamp', needed by `perl.mak'. Stop. make: *** [perl/perl.mak] Error 2 As you can see, at that time the place to look would be the makefile, so I would do think a 'fix' there would still be appropriate. Do you have a preference among the three options (comment, +recipe, drop)? -- Philip -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 3/6] bisect: use refs infrastructure for BISECT_START
On Thu, 2015-06-25 at 13:52 -0700, Junio C Hamano wrote: David Turner dtur...@twopensource.com writes: This ref needs to go through the refs backend, since some code assumes that it can be written and read as a ref. And the reason why BISECT_HEAD cannot be treated as a ref, but must be treated as a file under $GIT_DIR, is...? After running some tests on the long version of the series, we can and should move it into the backend; will add a patch to the next reroll -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] Revert stash: require a clean index to apply
Is this revert going to be applied and released? Sent from my Android device -Original Message- From: Junio C Hamano gits...@pobox.com To: Jeff King p...@peff.net Cc: bär crashcoo...@gmail.com, Jonathan Kamens jkam...@quantopian.com, Git List git@vger.kernel.org Sent: Mon, 15 Jun 2015 4:11 PM Subject: Re: [PATCH] Revert stash: require a clean index to apply Jeff King p...@peff.net writes: Subject: Revert stash: require a clean index to apply This reverts commit ed178ef13a26136d86ff4e33bb7b1afb5033f908. Thanks. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 5/6] git-reflog: add create and exists functions
On Thu, 2015-06-25 at 16:45 -0400, David Turner wrote: +static int cmd_reflog_create(int argc, const char **argv, const char *prefix) +{ While revising this patch, I noticed that safe_create_reflog (and this cmd_reflog_create) only creates reflogs for refs of the form that git itself would autocreate reflogs for. In other words, it won't create a reflog for foo, but will create a reflog for refs/heads/foo (even though that is very likely to already exist). So I'll fix that when I re-roll. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 5/5] bisect: allow any terms set by user
Matthieu Moy matthieu@imag.fr writes: + +git bisect terms term-new term-old + The mnemonic for git bisect start bad good is Bad comes before Good (B = 0x42, G = 0x47) and this is same for new/old, New comes before Old (N = 0x4e, O = 0x4f). git bisect terms new old follows the same pattern, which is good. Easy to remember. +This command has to be used before a bisection has started. term-old +must be associated with the latest revisions and term-new with the +ancestors of term-old. Whoa? This gets new and old mixed up, doesn't it? For example, if something was buggy in the +old part of the history, you know somewhere the bug was fixed, and you +want to find the exact commit that fixed it, you may want to say `git +bisect terms fixed broken`; this way, you would mark a commit that +still has the bug with `broken`, and a newer one after the fix with +`fixed`. So, it used to be broken, it got fixed recently, so broken is old, fixed is new, bad/new and then good/old mnemonic says you give fixed broken to bisect terms. OK. +Only the first bisection following the `git bisect terms` will use the +terms. If you mistyped one of the terms you can do again `git bisect +terms term-old term-new`. This is also the other way around, no? +git bisect terms term-new term-old + set up term-new and term-old as terms (default: bad, good) Good. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v9 4/5] bisect: add the terms old/new
On Thu, Jun 25, 2015 at 8:50 PM, Matthieu Moy matthieu@imag.fr wrote: [...] @@ -178,7 +183,7 @@ bisect_start() { } git rev-parse --sq-quote $@ $GIT_DIR/BISECT_NAMES eval $eval true - if test $revision_seen -eq 1 test ! -s $GIT_DIR/BISECT_TERMS + if test $must_write_terms -eq 1 test ! -s $GIT_DIR/BISECT_TERMS then echo $NAME_BAD $GIT_DIR/BISECT_TERMS echo $NAME_GOOD $GIT_DIR/BISECT_TERMS You are writing BISECT_TERMS here... @@ -543,14 +548,22 @@ check_and_set_terms () { fi NAME_BAD=bad NAME_GOOD=good ;; + new|old) + if ! test -s $GIT_DIR/BISECT_TERMS + then + echo new $GIT_DIR/BISECT_TERMS + echo old $GIT_DIR/BISECT_TERMS + fi + NAME_BAD=new + NAME_GOOD=old ;; ...and here nearly in the same way. So perhaps you could use a function like: write_bisect_terms() { if test ! -s $GIT_DIR/BISECT_TERMS then echo $NAME_BAD $GIT_DIR/BISECT_TERMS echo $NAME_GOOD $GIT_DIR/BISECT_TERMS fi } -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] Revert stash: require a clean index to apply
On Thu, Jun 25, 2015 at 09:12:55PM -0400, Jonathan Kamens wrote: I encountered this issue in git 2.4.3 on Fedora 22. Ah, sorry, you're right. I must have fed the wrong sha1 to git tag --contains earlier. I agree it can probably go onto the v2.4.x maintenance track. It is already in v2.5.0-rc0. -Peff -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] Revert stash: require a clean index to apply
On Thu, Jun 25, 2015 at 9:03 PM, Jeff King p...@peff.net wrote: On Thu, Jun 25, 2015 at 09:12:55PM -0400, Jonathan Kamens wrote: I encountered this issue in git 2.4.3 on Fedora 22. Ah, sorry, you're right. I must have fed the wrong sha1 to git tag --contains earlier. I agree it can probably go onto the v2.4.x maintenance track. It is already in v2.5.0-rc0. Yeah, thanks for clarifying while I was away. As with any other changes, a revert also follows the master first and then maintenance tracks later pattern. Perhaps in 2.4.6 which I expect we would do during the 2.5-rc period. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 3/6] bisect: use refs infrastructure for BISECT_START
On Thu, 2015-06-25 at 19:21 -0400, David Turner wrote: On Thu, 2015-06-25 at 13:52 -0700, Junio C Hamano wrote: David Turner dtur...@twopensource.com writes: This ref needs to go through the refs backend, since some code assumes that it can be written and read as a ref. And the reason why BISECT_HEAD cannot be treated as a ref, but must be treated as a file under $GIT_DIR, is...? After running some tests on the long version of the series, we can and should move it into the backend; will add a patch to the next reroll Actually, I've looked into this further. BISECT_START isn't a ref because it contains the ref name that the bisection started from (not a symbolic ref). BISECT_HEAD is a ref. Will fix. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] Revert stash: require a clean index to apply
On Thu, Jun 25, 2015 at 05:49:11PM -0400, Jonathan Kamens wrote: Is this revert going to be applied and released? It is on master, and part of v2.5.0-rc0 (it is not part of v2.4.x, because the original problem was not there, either). -Peff -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/7] refs.c: add err arguments to reflog functions
Add an err argument to log_ref_setup that can explain the reason for a failure. This then eliminates the need to manage errno through this function since we can just add strerror(errno) to the err string when meaningful. No callers relied on errno from this function for anything else than the error message. Also add err arguments to private functions write_ref_to_lockfile, log_ref_write_1, commit_ref_update. This again eliminates the need to manage errno in these functions. Update of a patch by Ronnie Sahlberg. Signed-off-by: Ronnie Sahlberg sahlb...@google.com Signed-off-by: David Turner dtur...@twopensource.com --- builtin/checkout.c | 8 ++-- refs.c | 111 - refs.h | 4 +- 3 files changed, 66 insertions(+), 57 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index c018ab3..93f63d3 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -624,16 +624,18 @@ static void update_refs_for_switch(const struct checkout_opts *opts, struct strbuf log_file = STRBUF_INIT; int ret; const char *ref_name; + struct strbuf err = STRBUF_INIT; ref_name = mkpath(refs/heads/%s, opts-new_orphan_branch); temp = log_all_ref_updates; log_all_ref_updates = 1; - ret = log_ref_setup(ref_name, log_file); + ret = log_ref_setup(ref_name, log_file, err); log_all_ref_updates = temp; strbuf_release(log_file); if (ret) { - fprintf(stderr, _(Can not do reflog for '%s'\n), - opts-new_orphan_branch); + fprintf(stderr, _(Can not do reflog for '%s'. %s\n), + opts-new_orphan_branch, err.buf); + strbuf_release(err); return; } } diff --git a/refs.c b/refs.c index fb568d7..b34a54a 100644 --- a/refs.c +++ b/refs.c @@ -2975,9 +2975,11 @@ static int rename_ref_available(const char *oldname, const char *newname) return ret; } -static int write_ref_to_lockfile(struct ref_lock *lock, const unsigned char *sha1); +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, -const unsigned char *sha1, const char *logmsg); +const unsigned char *sha1, const char *logmsg, +struct strbuf *err); int rename_ref(const char *oldrefname, const char *newrefname, const char *logmsg) { @@ -3038,9 +3040,10 @@ 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) || - commit_ref_update(lock, orig_sha1, logmsg)) { - error(unable to write current sha1 into %s, newrefname); + if (write_ref_to_lockfile(lock, orig_sha1, err) || + commit_ref_update(lock, orig_sha1, logmsg, err)) { + error(unable to write current sha1 into %s: %s, newrefname, err.buf); + strbuf_release(err); goto rollback; } @@ -3056,9 +3059,11 @@ 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) || - commit_ref_update(lock, orig_sha1, NULL)) - error(unable to write current sha1 into %s, oldrefname); + if (write_ref_to_lockfile(lock, orig_sha1, err) || + commit_ref_update(lock, orig_sha1, NULL, err)) { + error(unable to write current sha1 into %s: %s, oldrefname, err.buf); + strbuf_release(err); + } log_all_ref_updates = flag; rollbacklog: @@ -3113,8 +3118,8 @@ static int copy_msg(char *buf, const char *msg) return cp - buf; } -/* This function must set a meaningful errno on failure */ -int log_ref_setup(const char *refname, struct strbuf *sb_logfile) +/* This function will fill in *err and return -1 on failure */ +int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf *err) { int logfd, oflags = O_APPEND | O_WRONLY; char *logfile; @@ -3129,9 +3134,8 @@ int log_ref_setup(const char *refname, struct strbuf *sb_logfile) starts_with(refname, refs/notes/) ||
[PATCH v3 5/7] refs: add safe_create_reflog function
Make log_ref_setup private, and add public safe_create_reflog which calls log_ref_setup. In a moment, we will use safe_create_reflog to add reflog creation commands to git-reflog. Signed-off-by: David Turner dtur...@twopensource.com --- builtin/checkout.c | 4 +--- refs.c | 19 --- refs.h | 2 +- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index 93f63d3..55e4fbc 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -621,7 +621,6 @@ static void update_refs_for_switch(const struct checkout_opts *opts, if (opts-new_orphan_branch) { if (opts-new_branch_log !log_all_ref_updates) { int temp; - struct strbuf log_file = STRBUF_INIT; int ret; const char *ref_name; struct strbuf err = STRBUF_INIT; @@ -629,9 +628,8 @@ static void update_refs_for_switch(const struct checkout_opts *opts, ref_name = mkpath(refs/heads/%s, opts-new_orphan_branch); temp = log_all_ref_updates; log_all_ref_updates = 1; - ret = log_ref_setup(ref_name, log_file, err); + ret = safe_create_reflog(ref_name, err, 0); log_all_ref_updates = temp; - strbuf_release(log_file); if (ret) { fprintf(stderr, _(Can not do reflog for '%s'. %s\n), opts-new_orphan_branch, err.buf); diff --git a/refs.c b/refs.c index dff91cf..7519dac 100644 --- a/refs.c +++ b/refs.c @@ -3123,11 +3123,12 @@ static int should_autocreate_reflog(const char *refname) return starts_with(refname, refs/heads/) || starts_with(refname, refs/remotes/) || starts_with(refname, refs/notes/) || + !strcmp(refname, refs/stash) || !strcmp(refname, HEAD); } /* This function will fill in *err and return -1 on failure */ -int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf *err) +static int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf *err, int force_create) { int logfd, oflags = O_APPEND | O_WRONLY; char *logfile; @@ -3136,7 +3137,8 @@ int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf logfile = sb_logfile-buf; /* make sure the rest of the function can't change logfile */ sb_logfile = NULL; - if (log_all_ref_updates should_autocreate_reflog(refname)) { + if (log_all_ref_updates + (force_create || should_autocreate_reflog(refname))) { if (safe_create_leading_directories(logfile) 0) { strbuf_addf(err, unable to create directory for %s. %s, logfile, strerror(errno)); @@ -3171,6 +3173,17 @@ int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf return 0; } + +int safe_create_reflog(const char *refname, struct strbuf *err, int force_create) +{ + int ret; + struct strbuf sb = STRBUF_INIT; + + ret = log_ref_setup(refname, sb, err, force_create); + strbuf_release(sb); + return ret; +} + static int log_ref_write_fd(int fd, const unsigned char *old_sha1, const unsigned char *new_sha1, const char *committer, const char *msg) @@ -3207,7 +3220,7 @@ static int log_ref_write_1(const char *refname, const unsigned char *old_sha1, if (log_all_ref_updates 0) log_all_ref_updates = !is_bare_repository(); - result = log_ref_setup(refname, sb_log_file, err); + result = log_ref_setup(refname, sb_log_file, err, 0); if (result) return result; diff --git a/refs.h b/refs.h index debdefc..3b90e16 100644 --- a/refs.h +++ b/refs.h @@ -228,7 +228,7 @@ int pack_refs(unsigned int flags); /* * Setup reflog before using. Fill in err and return -1 on failure. */ -int log_ref_setup(const char *refname, struct strbuf *logfile, struct strbuf *err); +int safe_create_reflog(const char *refname, struct strbuf *err, int force_create); /** Reads log for the value of ref during at_time. **/ extern int read_ref_at(const char *refname, unsigned int flags, -- 2.0.4.314.gdbf7a51-twtrsrc -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/7] cherry-pick: treat CHERRY_PICK_HEAD and REVERT_HEAD as refs
Instead of directly writing to and reading from files in $GIT_DIR, use ref API to interact with CHERRY_PICK_HEAD and REVERT_HEAD. Signed-off-by: David Turner dtur...@twopensource.com --- branch.c | 4 ++-- builtin/commit.c | 6 +++--- builtin/merge.c | 2 +- contrib/completion/git-prompt.sh | 4 ++-- git-gui/lib/commit.tcl | 2 +- sequencer.c | 37 +++-- t/t7509-commit.sh| 4 ++-- wt-status.c | 6 ++ 8 files changed, 32 insertions(+), 33 deletions(-) diff --git a/branch.c b/branch.c index b002435..ec598aa 100644 --- a/branch.c +++ b/branch.c @@ -302,8 +302,8 @@ void create_branch(const char *head, void remove_branch_state(void) { - unlink(git_path(CHERRY_PICK_HEAD)); - unlink(git_path(REVERT_HEAD)); + delete_ref(CHERRY_PICK_HEAD, NULL, REF_NODEREF); + delete_ref(REVERT_HEAD, NULL, REF_NODEREF); unlink(git_path(MERGE_HEAD)); unlink(git_path(MERGE_RR)); unlink(git_path(MERGE_MSG)); diff --git a/builtin/commit.c b/builtin/commit.c index b5b1158..53c7e90 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -168,7 +168,7 @@ static void determine_whence(struct wt_status *s) { if (file_exists(git_path(MERGE_HEAD))) whence = FROM_MERGE; - else if (file_exists(git_path(CHERRY_PICK_HEAD))) { + else if (ref_exists(CHERRY_PICK_HEAD)) { whence = FROM_CHERRY_PICK; if (file_exists(git_path(SEQ_DIR))) sequencer_in_use = 1; @@ -1777,8 +1777,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix) } ref_transaction_free(transaction); - unlink(git_path(CHERRY_PICK_HEAD)); - unlink(git_path(REVERT_HEAD)); + delete_ref(CHERRY_PICK_HEAD, NULL, REF_NODEREF); + delete_ref(REVERT_HEAD, NULL, REF_NODEREF); unlink(git_path(MERGE_HEAD)); unlink(git_path(MERGE_MSG)); unlink(git_path(MERGE_MODE)); diff --git a/builtin/merge.c b/builtin/merge.c index 46aacd6..3e2ae2f 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -1206,7 +1206,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) else die(_(You have not concluded your merge (MERGE_HEAD exists).)); } - if (file_exists(git_path(CHERRY_PICK_HEAD))) { + if (ref_exists(CHERRY_PICK_HEAD)) { if (advice_resolve_conflict) die(_(You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n Please, commit your changes before you merge.)); diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index 366f0bc..e2c5583 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -415,9 +415,9 @@ __git_ps1 () fi elif [ -f $g/MERGE_HEAD ]; then r=|MERGING - elif [ -f $g/CHERRY_PICK_HEAD ]; then + elif git rev-parse --quiet --verify CHERRY_PICK_HEAD /dev/null; then r=|CHERRY-PICKING - elif [ -f $g/REVERT_HEAD ]; then + elif git rev-parse --quiet --verify REVERT_HEAD /dev/null; then r=|REVERTING elif [ -f $g/BISECT_LOG ]; then r=|BISECTING diff --git a/git-gui/lib/commit.tcl b/git-gui/lib/commit.tcl index 864b687..2b08b13 100644 --- a/git-gui/lib/commit.tcl +++ b/git-gui/lib/commit.tcl @@ -409,7 +409,7 @@ A rescan will be automatically started now. catch {file delete [gitdir MERGE_MSG]} catch {file delete [gitdir SQUASH_MSG]} catch {file delete [gitdir GITGUI_MSG]} - catch {file delete [gitdir CHERRY_PICK_HEAD]} + catch {git update-ref -d --no-deref CHERRY_PICK_HEAD} # -- Let rerere do its thing. # diff --git a/sequencer.c b/sequencer.c index f8421a8..de904aa 100644 --- a/sequencer.c +++ b/sequencer.c @@ -160,19 +160,20 @@ static void free_message(struct commit *commit, struct commit_message *msg) static void write_cherry_pick_head(struct commit *commit, const char *pseudoref) { - const char *filename; - int fd; - struct strbuf buf = STRBUF_INIT; + struct strbuf err = STRBUF_INIT; + void *transaction; - strbuf_addf(buf, %s\n, sha1_to_hex(commit-object.sha1)); + transaction = ref_transaction_begin(err); + if (!transaction) + die(_(Could not create transaction: %s), err.buf); - filename = git_path(%s, pseudoref); - fd = open(filename, O_WRONLY | O_CREAT, 0666); - if (fd 0) - die_errno(_(Could not open '%s' for writing), filename); - if (write_in_full(fd, buf.buf, buf.len) != buf.len || close(fd)) - die_errno(_(Could not write
[PATCH v3 6/7] git-reflog: add create and exists functions
These are necessary because alternate ref backends might store reflogs somewhere other than .git/logs. Code that now directly manipulates .git/logs should instead go through git-reflog. In a moment, we will use these functions to make git stash work with alternate ref backends. Signed-off-by: David Turner dtur...@twopensource.com --- builtin/reflog.c | 79 +- t/t1411-reflog-show.sh | 12 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/builtin/reflog.c b/builtin/reflog.c index c2eb8ff..7fe31fa 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -13,6 +13,10 @@ static const char reflog_expire_usage[] = git reflog expire [--expire=time] [--expire-unreachable=time] [--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] [--verbose] [--all] refs...; static const char reflog_delete_usage[] = git reflog delete [--rewrite] [--updateref] [--dry-run | -n] [--verbose] refs...; +static const char reflog_create_usage[] = +git reflog create refs...; +static const char reflog_exists_usage[] = +git reflog exists ref; static unsigned long default_reflog_expire; static unsigned long default_reflog_expire_unreachable; @@ -699,12 +703,79 @@ static int cmd_reflog_delete(int argc, const char **argv, const char *prefix) return status; } +static int cmd_reflog_create(int argc, const char **argv, const char *prefix) +{ + int i, status = 0, start = 0; + struct strbuf err = STRBUF_INIT; + int temp; + + for (i = 1; i argc; i++) { + const char *arg = argv[i]; + if (!strcmp(arg, --)) { + i++; + break; + } + else if (arg[0] == '-') + usage(reflog_create_usage); + else + break; + } + + start = i; + + if (argc - start 1) + return error(Nothing to create?); + + temp = log_all_ref_updates; + log_all_ref_updates = 1; + for (i = start; i argc; i++) { + if (check_refname_format(argv[i], REFNAME_ALLOW_ONELEVEL)) + die(invalid ref format: %s, argv[i]); + } + for (i = start; i argc; i++) { + if (safe_create_reflog(argv[i], err, 1)) { + error(could not create reflog %s: %s, argv[i], + err.buf); + status = 1; + strbuf_release(err); + } + } + log_all_ref_updates = temp; + return status; +} + +static int cmd_reflog_exists(int argc, const char **argv, const char *prefix) +{ + int i, status = 0, start = 0; + + for (i = 1; i argc; i++) { + const char *arg = argv[i]; + if (!strcmp(arg, --)) { + i++; + break; + } + else if (arg[0] == '-') + usage(reflog_exists_usage); + else + break; + } + + start = i; + + if (argc - start != 1) + usage(reflog_exists_usage); + + if (check_refname_format(argv[start], REFNAME_ALLOW_ONELEVEL)) + die(invalid ref format: %s, argv[start]); + return !reflog_exists(argv[start]); +} + /* * main reflog */ static const char reflog_usage[] = -git reflog [ show | expire | delete ]; +git reflog [ show | expire | delete | create | exists ]; int cmd_reflog(int argc, const char **argv, const char *prefix) { @@ -724,5 +795,11 @@ int cmd_reflog(int argc, const char **argv, const char *prefix) if (!strcmp(argv[1], delete)) return cmd_reflog_delete(argc - 1, argv + 1, prefix); + if (!strcmp(argv[1], create)) + return cmd_reflog_create(argc - 1, argv + 1, prefix); + + if (!strcmp(argv[1], exists)) + return cmd_reflog_exists(argc - 1, argv + 1, prefix); + return cmd_log_reflog(argc, argv, prefix); } diff --git a/t/t1411-reflog-show.sh b/t/t1411-reflog-show.sh index 6f47c0d..6e1abe7 100755 --- a/t/t1411-reflog-show.sh +++ b/t/t1411-reflog-show.sh @@ -166,4 +166,16 @@ test_expect_success 'git log -g -p shows diffs vs. parents' ' test_cmp expect actual ' +test_expect_success 'reflog exists works' ' + git reflog exists refs/heads/master + ! git reflog exists refs/heads/nonexistent +' + +test_expect_success 'reflog create works' ' + git update-ref non-refs-dir HEAD + ! git reflog exists non-refs-dir + git reflog create non-refs-dir + git reflog exists non-refs-dir +' + test_done -- 2.0.4.314.gdbf7a51-twtrsrc -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html