* Re: Tag peeling peculiarities
From: Michael Haggerty @ 2013-03-13 15:34 UTC (permalink / raw)
To: git discussion list; +Cc: Junio C Hamano
In-Reply-To: <51409439.5090001@alum.mit.edu>
On 03/13/2013 03:59 PM, Michael Haggerty wrote:
> I have been working on the pack-refs code [1] and noticed what looks
> like a problem with the handling of peeled refs in the packed-refs file
> and in the reference cache. In particular, the peeled versions of tags
> outside of refs/tags are *not* stored in packed-refs, but after the
> packed-refs file is read it is assumed that such tags cannot be peeled.
>
> It is clear that annotated tags want to live under refs/tags, but there
> are some ways to create them in other places (see below). It is not
> clear to me whether the prohibition of tags outside of refs/tags should
> be made more airtight or whether the peeling of tags outside of
> refs/tags should be fixed.
>
> Example:
> [...]
I should have mentioned that I already understand the programmatic
*cause* of the behavior that I described in my last email:
* in pack-refs.c:handle_one_ref(), tags that are not in refs/tags are
explicitly excluded from being peeled.
* in refs.c:read_packed_refs(), if the packed-refs file starts with
"# pack-refs with: peeled "
then the REF_KNOWS_PEELED bit is set on *every* reference read from
the file into the packed refs cache, whether or not it is under
refs/tags.
* in refs.c:peel_ref(), if a refs cache entry has its REF_KNOWS_PEELED
bit set but its peeled field is empty, then it is assumed that the
reference is unpeelable.
What I am *not* clear about is which of these steps is incorrect, and
also whether this problem will have any significant ill effects.
Michael
--
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
^ permalink raw reply
* Re: difftool -d symlinks, under what conditions
From: Junio C Hamano @ 2013-03-13 15:30 UTC (permalink / raw)
To: David Aguilar
Cc: John Keeping, Matt McClure, git@vger.kernel.org, Tim Henigan
In-Reply-To: <CAJDDKr7ZU16XWtCfYX9-RMzcpKa_FF80Od+mUMG4n8dUKeLsvw@mail.gmail.com>
David Aguilar <davvid@gmail.com> writes:
>> The implementation of Junio's suggestion is relatively straightforward
>> (this is untested, although t7800 passes, and can probably be improved
>> by someone better versed in Perl). Does this work for your original
>> scenario?
>
> This is a nice straightforward approach.
>
> As Junio mentioned, a good next step would be this patch in
> combination with making the truly temporary files created by
> dir-diff readonly.
Even though I agree that the idea Matt McClure mentioned to run a
three-way merge to take the modification back when the path checked
out to the temporary tree as a temporary file (because it does not
match the working tree version) gets edited by the user might be a
better longer-term direction to go, marking the temporaries that the
users should not modify clearly as such needs to be done in the
shorter term. This thread wouldn't have had to happen if we had
such a safety measure in the first place.
^ permalink raw reply
* [PATCH] difftool: Make directory diff symlink working tree
From: Matt McClure @ 2013-03-13 15:21 UTC (permalink / raw)
To: David Aguilar
Cc: John Keeping, Junio C Hamano, git@vger.kernel.org, Tim Henigan
On Wed, Mar 13, 2013 at 4:24 AM, David Aguilar <davvid@gmail.com> wrote:
> This is a nice straightforward approach.
>
> As Junio mentioned, a good next step would be this patch
> in combination with making the truly temporary files
> created by dir-diff readonly.
>
> Will that need a win32 platform check?
> Does anyone want to take this and whip it into a proper patch?
An attempt:
>From 429ae282ffd7202b6d2fb024a92dea543b8af376 Mon Sep 17 00:00:00 2001
From: Matt McClure <matthewlmcclure@gmail.com>
Date: Wed, 13 Mar 2013 11:14:22 -0400
Subject: [PATCH] difftool: Make directory diff symlink working tree
...primarily so that a user can edit working tree files in his difftool.
difftool -d formerly knew how to symlink to the working tree when the
work tree contains uncommitted changes. In practice, prior to this
change, it would not symlink to the working tree in case there were no
uncommitted changes, even when the user invoked difftool with the form:
git difftool -d [--options] <commit> [--] [<path>...]
This form is to view the changes you have in your working tree
relative to the named <commit>. You can use HEAD to compare it
with the latest commit, or a branch name to compare with the tip
of a different branch.
Instead, prior to this change, difftool would use the file's blob SHA1
to find its content in the index rather than use the working tree
content. This change teaches `git difftool` to compare the blob SHA1 to
the file's working tree blob SHA1 and use the working tree file if the
SHA1s are the same.
Author: John Keeping <john@keeping.me.uk>
Conversation:
http://thread.gmane.org/gmane.comp.version-control.git/217979/focus=218014
---
git-difftool.perl | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/git-difftool.perl b/git-difftool.perl
index 0a90de4..5f093ae 100755
--- a/git-difftool.perl
+++ b/git-difftool.perl
@@ -83,6 +83,21 @@ sub exit_cleanup
exit($status | ($status >> 8));
}
+sub use_wt_file
+{
+ my ($repo, $workdir, $file, $sha1, $symlinks) = @_;
+ my $null_sha1 = '0' x 40;
+
+ if ($sha1 eq $null_sha1) {
+ return 1;
+ } elsif (not $symlinks) {
+ return 0;
+ }
+
+ my $wt_sha1 = $repo->command_oneline('hash-object', "$workdir/$file");
+ return $sha1 eq $wt_sha1;
+}
+
sub setup_dir_diff
{
my ($repo, $workdir, $symlinks) = @_;
@@ -159,10 +174,10 @@ EOF
}
if ($rmode ne $null_mode) {
- if ($rsha1 ne $null_sha1) {
- $rindex .= "$rmode $rsha1\t$dst_path\0";
- } else {
+ if (use_wt_file($repo, $workdir, $dst_path, $rsha1, $symlinks)) {
push(@working_tree, $dst_path);
+ } else {
+ $rindex .= "$rmode $rsha1\t$dst_path\0";
}
}
}
--
1.8.1.5
--
Matt McClure
http://www.matthewlmcclure.com
http://www.mapmyfitness.com/profile/matthewlmcclure
^ permalink raw reply related
* Re: [PATCH] status: hint the user about -uno if read_directory takes too long
From: Torsten Bögershausen @ 2013-03-13 15:21 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy
Cc: git, Junio C Hamano, tboegi, artagnon, robert.allan.zeh, finnag
In-Reply-To: <1363179556-4144-1-git-send-email-pclouds@gmail.com>
On 13.03.13 13:59, Nguyễn Thái Ngọc Duy wrote:
> This patch attempts to advertise -uno to the users who tolerate slow
> "git status" on large repositories (or slow machines/disks). The 2
> seconds limit is quite arbitrary but is probably long enough to start
> using -uno.
>
> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
> ---
> Documentation/config.txt | 4 ++++
> advice.c | 2 ++
> advice.h | 1 +
> t/t7060-wtstatus.sh | 2 ++
> t/t7508-status.sh | 4 ++++
> t/t7512-status-help.sh | 1 +
> wt-status.c | 20 +++++++++++++++++++-
> wt-status.h | 1 +
> 8 files changed, 34 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/config.txt b/Documentation/config.txt
> index bbba728..e91d06f 100644
> --- a/Documentation/config.txt
> +++ b/Documentation/config.txt
> @@ -178,6 +178,10 @@ advice.*::
> the template shown when writing commit messages in
> linkgit:git-commit[1], and in the help message shown
> by linkgit:git-checkout[1] when switching branch.
> + statusUno::
> + If collecting untracked files in linkgit:git-status[1]
> + takes more than 2 seconds, hint the user that the option
> + `-uno` could be used to stop collecting untracked files.
Thanks, I like the idea
could we make a "de-Luxe" version where
statusUno is an integer, counting in milliseconds?
/Torsten
^ permalink raw reply
* Tag peeling peculiarities
From: Michael Haggerty @ 2013-03-13 14:59 UTC (permalink / raw)
To: git discussion list; +Cc: Junio C Hamano
I have been working on the pack-refs code [1] and noticed what looks
like a problem with the handling of peeled refs in the packed-refs file
and in the reference cache. In particular, the peeled versions of tags
outside of refs/tags are *not* stored in packed-refs, but after the
packed-refs file is read it is assumed that such tags cannot be peeled.
It is clear that annotated tags want to live under refs/tags, but there
are some ways to create them in other places (see below). It is not
clear to me whether the prohibition of tags outside of refs/tags should
be made more airtight or whether the peeling of tags outside of
refs/tags should be fixed.
Example:
~/tmp$ git init foo
Initialized empty Git repository in /home/mhagger/tmp/foo/.git/
~/tmp$ cd foo
~/tmp/foo$ git config user.name 'Lou User'
~/tmp/foo$ git config user.email 'luser@exaple.com'
~/tmp/foo$
~/tmp/foo$ git commit --allow-empty -m "Initial commit"
[master (root-commit) 7e80ddd] Initial commit
~/tmp/foo$ git tag -m footag footag
~/tmp/foo$
~/tmp/foo$ # This is prohibited:
~/tmp/foo$ git update-ref refs/heads/foobranch $(git rev-parse footag)
error: Trying to write non-commit object
d9cdc84dd156ff83799f5226794711fbb2c8273a to branch refs/heads/foobranch
fatal: Cannot update the ref 'refs/heads/foobranch'.
~/tmp/foo$
~/tmp/foo$ # But this is allowed:
~/tmp/foo$ git update-ref refs/remotes/foo/bar $(git rev-parse footag)
~/tmp/foo$
~/tmp/foo$ # So is this:
~/tmp/foo$ git update-ref refs/yak/foobranch $(git rev-parse footag)
~/tmp/foo$
~/tmp/foo$ # Before packing, all tags are available in peel versions:
~/tmp/foo$ git show-ref -d
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/heads/master
d9cdc84dd156ff83799f5226794711fbb2c8273a refs/remotes/foo/bar
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/remotes/foo/bar^{}
d9cdc84dd156ff83799f5226794711fbb2c8273a refs/tags/footag
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/tags/footag^{}
d9cdc84dd156ff83799f5226794711fbb2c8273a refs/yak/foobranch
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/yak/foobranch^{}
~/tmp/foo$
~/tmp/foo$ git pack-refs --all
~/tmp/foo$
~/tmp/foo$ # After packing, tags outside of refs/tags are not peeled any
more:
~/tmp/foo$ git show-ref -d
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/heads/master
d9cdc84dd156ff83799f5226794711fbb2c8273a refs/remotes/foo/bar
d9cdc84dd156ff83799f5226794711fbb2c8273a refs/tags/footag
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/tags/footag^{}
d9cdc84dd156ff83799f5226794711fbb2c8273a refs/yak/foobranch
~/tmp/foo$
~/tmp/foo$ # Peeling the tags via "tag^0" works even after packing:
~/tmp/foo$ git rev-parse refs/yak/foobranch^0
7e80ddd68f0225a0ea221f7cddbacf050be5a265
~/tmp/foo$
~/tmp/foo$ # Here is another way to create a tag outside of refs/tags:
~/tmp/foo$ cd ..
~/tmp$ git clone foo foo-clone
Cloning into 'foo-clone'...
done.
~/tmp$ cd foo-clone
~/tmp/foo-clone$ git config --add remote.origin.fetch
'+refs/tags/*:refs/remotes/origin/tags/*'
~/tmp/foo-clone$ git fetch
From /home/mhagger/tmp/foo
* [new tag] footag -> origin/tags/footag
~/tmp/foo-clone$
~/tmp/foo-clone$ # Again, the tag outside of refs/tags are not peeled
correctly after packing:
~/tmp/foo-clone$ git pack-refs --all
~/tmp/foo-clone$ git show-ref -d
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/heads/master
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/remotes/origin/HEAD
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/remotes/origin/master
d9cdc84dd156ff83799f5226794711fbb2c8273a refs/remotes/origin/tags/footag
d9cdc84dd156ff83799f5226794711fbb2c8273a refs/tags/footag
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/tags/footag^{}
Michael
[1] I am trying to fix the problem that peeled refs are lost whenever a
packed reference is deleted.
--
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
^ permalink raw reply
* Rename conflicts in the index
From: Edward Thomson @ 2013-03-13 14:08 UTC (permalink / raw)
To: git@vger.kernel.org
When a rename conflict occurs, the information about the conflict is
written to stdout and the index is updated as if the conflict were a
simpler conflict that did not involve renames. This doesn't give a lot of
information to users after the fact - a status of "added in ours" does not
provide a lot of details about what occurred.
In reimplementations, we face a similar challenge. Unfortunately, we can't
simply print the output to the console, we would like to provide this
information back to the caller by some mechanism. My preference would be to
return this information in the index - so that the results of "unpack trees"
(if you will) was a single data structure (the index) and so that we could
persist this information to disk. I've been considering the idea of an
extension that contains more detailed data about conflicts, but I certainly
wouldn't want to proceed without discussing this here further.
I would propose that we store the data about the file in conflict as it
occurred through the renames. For example, in a rename 1->2 conflict where
A was renamed to both B and C, you would have a single conflict entry
containing the data for A, B and C. This would allow us to provide more
detailed information to the user - and allow them to (say) choose a single
name to proceed with.
Is this something that has value to core git as well? Alternately, is
there something particularly stupid about this proposal?
Thanks-
-ed
^ permalink raw reply
* [PATCH] status: hint the user about -uno if read_directory takes too long
From: Nguyễn Thái Ngọc Duy @ 2013-03-13 12:59 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, tboegi, artagnon, robert.allan.zeh, finnag,
Nguyễn Thái Ngọc Duy
In-Reply-To: <CACsJy8DZm153Tu_3GTOnxF8bFrYPh7_DP6Rn6rr3n6tfuVuv2Q@mail.gmail.com>
This patch attempts to advertise -uno to the users who tolerate slow
"git status" on large repositories (or slow machines/disks). The 2
seconds limit is quite arbitrary but is probably long enough to start
using -uno.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/config.txt | 4 ++++
advice.c | 2 ++
advice.h | 1 +
t/t7060-wtstatus.sh | 2 ++
t/t7508-status.sh | 4 ++++
t/t7512-status-help.sh | 1 +
wt-status.c | 20 +++++++++++++++++++-
wt-status.h | 1 +
8 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index bbba728..e91d06f 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -178,6 +178,10 @@ advice.*::
the template shown when writing commit messages in
linkgit:git-commit[1], and in the help message shown
by linkgit:git-checkout[1] when switching branch.
+ statusUno::
+ If collecting untracked files in linkgit:git-status[1]
+ takes more than 2 seconds, hint the user that the option
+ `-uno` could be used to stop collecting untracked files.
commitBeforeMerge::
Advice shown when linkgit:git-merge[1] refuses to
merge to avoid overwriting local changes.
diff --git a/advice.c b/advice.c
index 780f58d..72b5c66 100644
--- a/advice.c
+++ b/advice.c
@@ -8,6 +8,7 @@ int advice_push_already_exists = 1;
int advice_push_fetch_first = 1;
int advice_push_needs_force = 1;
int advice_status_hints = 1;
+int advice_status_uno = 1;
int advice_commit_before_merge = 1;
int advice_resolve_conflict = 1;
int advice_implicit_identity = 1;
@@ -25,6 +26,7 @@ static struct {
{ "pushfetchfirst", &advice_push_fetch_first },
{ "pushneedsforce", &advice_push_needs_force },
{ "statushints", &advice_status_hints },
+ { "statusuno", &advice_status_uno },
{ "commitbeforemerge", &advice_commit_before_merge },
{ "resolveconflict", &advice_resolve_conflict },
{ "implicitidentity", &advice_implicit_identity },
diff --git a/advice.h b/advice.h
index fad36df..d7e03be 100644
--- a/advice.h
+++ b/advice.h
@@ -11,6 +11,7 @@ extern int advice_push_already_exists;
extern int advice_push_fetch_first;
extern int advice_push_needs_force;
extern int advice_status_hints;
+extern int advice_status_uno;
extern int advice_commit_before_merge;
extern int advice_resolve_conflict;
extern int advice_implicit_identity;
diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh
index f4f38a5..dd340d5 100755
--- a/t/t7060-wtstatus.sh
+++ b/t/t7060-wtstatus.sh
@@ -5,6 +5,7 @@ test_description='basic work tree status reporting'
. ./test-lib.sh
test_expect_success setup '
+ git config advice.statusuno false &&
test_commit A &&
test_commit B oneside added &&
git checkout A^0 &&
@@ -46,6 +47,7 @@ test_expect_success 'M/D conflict does not segfault' '
(
cd mdconflict &&
git init &&
+ git config advice.statusuno false
test_commit initial foo "" &&
test_commit modify foo foo &&
git checkout -b side HEAD^ &&
diff --git a/t/t7508-status.sh b/t/t7508-status.sh
index a79c032..9d6e4db 100755
--- a/t/t7508-status.sh
+++ b/t/t7508-status.sh
@@ -8,11 +8,13 @@ test_description='git status'
. ./test-lib.sh
test_expect_success 'status -h in broken repository' '
+ git config advice.statusuno false &&
mkdir broken &&
test_when_finished "rm -fr broken" &&
(
cd broken &&
git init &&
+ git config advice.statusuno false &&
echo "[status] showuntrackedfiles = CORRUPT" >>.git/config &&
test_expect_code 129 git status -h >usage 2>&1
) &&
@@ -25,6 +27,7 @@ test_expect_success 'commit -h in broken repository' '
(
cd broken &&
git init &&
+ git config advice.statusuno false &&
echo "[status] showuntrackedfiles = CORRUPT" >>.git/config &&
test_expect_code 129 git commit -h >usage 2>&1
) &&
@@ -780,6 +783,7 @@ test_expect_success 'status refreshes the index' '
test_expect_success 'setup status submodule summary' '
test_create_repo sm && (
cd sm &&
+ git config advice.statusuno false &&
>foo &&
git add foo &&
git commit -m "Add foo"
diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
index d2da89a..033a1b3 100755
--- a/t/t7512-status-help.sh
+++ b/t/t7512-status-help.sh
@@ -14,6 +14,7 @@ test_description='git status advice'
set_fake_editor
test_expect_success 'prepare for conflicts' '
+ git config advice.statusuno false &&
test_commit init main.txt init &&
git branch conflicts &&
test_commit on_master main.txt on_master &&
diff --git a/wt-status.c b/wt-status.c
index ef405d0..6fde08b 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -540,7 +540,16 @@ void wt_status_collect(struct wt_status *s)
wt_status_collect_changes_initial(s);
else
wt_status_collect_changes_index(s);
- wt_status_collect_untracked(s);
+ if (s->show_untracked_files && advice_status_uno) {
+ struct timeval tv1, tv2;
+ gettimeofday(&tv1, NULL);
+ wt_status_collect_untracked(s);
+ gettimeofday(&tv2, NULL);
+ s->untracked_in_ms =
+ (uint64_t)tv2.tv_sec * 1000 + tv2.tv_usec / 1000 -
+ ((uint64_t)tv1.tv_sec * 1000 + tv1.tv_usec / 1000);
+ } else
+ wt_status_collect_untracked(s);
}
static void wt_status_print_unmerged(struct wt_status *s)
@@ -1097,6 +1106,15 @@ void wt_status_print(struct wt_status *s)
wt_status_print_other(s, &s->untracked, _("Untracked files"), "add");
if (s->show_ignored_files)
wt_status_print_other(s, &s->ignored, _("Ignored files"), "add -f");
+ if (advice_status_uno && s->untracked_in_ms > 2000) {
+ status_printf_ln(s, GIT_COLOR_NORMAL,
+ _("It took %.2f seconds to collect untracked files."),
+ (float)s->untracked_in_ms / 1000);
+ status_printf_ln(s, GIT_COLOR_NORMAL,
+ _("If it happens often, you may want to use option -uno"));
+ status_printf_ln(s, GIT_COLOR_NORMAL,
+ _("to speed up by stopping displaying untracked files"));
+ }
} else if (s->commitable)
status_printf_ln(s, GIT_COLOR_NORMAL, _("Untracked files not listed%s"),
advice_status_hints
diff --git a/wt-status.h b/wt-status.h
index 81e1dcf..74208c0 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -69,6 +69,7 @@ struct wt_status {
struct string_list change;
struct string_list untracked;
struct string_list ignored;
+ uint32_t untracked_in_ms;
};
struct wt_status_state {
--
1.8.1.2.536.gf441e6d
^ permalink raw reply related
* [PATCH v3 5/5] branch: show more information when HEAD is detached
From: Nguyễn Thái Ngọc Duy @ 2013-03-13 11:42 UTC (permalink / raw)
To: git
Cc: Matthieu Moy, Jonathan Niedier, Junio C Hamano,
Nguyễn Thái Ngọc Duy
In-Reply-To: <1363174973-17597-1-git-send-email-pclouds@gmail.com>
This prints more helpful info when HEAD is detached: is it detached
because of bisect or rebase? What is the original branch name in those
cases? Is it detached because the user checks out a remote ref or a
tag (and which one)?
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/branch.c | 26 +++++++++++++++++++++++++-
t/t3203-branch-output.sh | 6 +++---
t/t6030-bisect-porcelain.sh | 2 +-
3 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/builtin/branch.c b/builtin/branch.c
index 00d17d2..2ab0e4f 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -18,6 +18,7 @@
#include "string-list.h"
#include "column.h"
#include "utf8.h"
+#include "wt-status.h"
static const char * const builtin_branch_usage[] = {
N_("git branch [options] [-r | -a] [--merged | --no-merged]"),
@@ -550,6 +551,29 @@ static int calc_maxwidth(struct ref_list *refs)
return w;
}
+static char *get_head_description(void)
+{
+ struct strbuf desc = STRBUF_INIT;
+ struct wt_status_state state;
+ memset(&state, 0, sizeof(state));
+ wt_status_get_state(&state, 1);
+ if (state.rebase_in_progress ||
+ state.rebase_interactive_in_progress)
+ strbuf_addf(&desc, _("(no branch, rebasing %s)"),
+ state.branch);
+ else if (state.bisect_in_progress)
+ strbuf_addf(&desc, _("(no branch, bisecting %s)"),
+ state.branch);
+ else if (state.detached_from)
+ strbuf_addf(&desc, _("(detached from %s)"),
+ state.detached_from);
+ else
+ strbuf_addstr(&desc, _("(no branch)"));
+ free(state.branch);
+ free(state.onto);
+ free(state.detached_from);
+ return strbuf_detach(&desc, NULL);
+}
static void show_detached(struct ref_list *ref_list)
{
@@ -557,7 +581,7 @@ static void show_detached(struct ref_list *ref_list)
if (head_commit && is_descendant_of(head_commit, ref_list->with_commit)) {
struct ref_item item;
- item.name = xstrdup(_("(no branch)"));
+ item.name = get_head_description();
item.width = utf8_strwidth(item.name);
item.kind = REF_LOCAL_BRANCH;
item.dest = NULL;
diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh
index 76fe7e0..ba4f98e 100755
--- a/t/t3203-branch-output.sh
+++ b/t/t3203-branch-output.sh
@@ -94,13 +94,13 @@ test_expect_success 'git branch -v pattern does not show branch summaries' '
test_must_fail git branch -v branch*
'
-cat >expect <<'EOF'
-* (no branch)
+test_expect_success 'git branch shows detached HEAD properly' '
+ cat >expect <<EOF &&
+* (detached from $(git rev-parse --short HEAD^0))
branch-one
branch-two
master
EOF
-test_expect_success 'git branch shows detached HEAD properly' '
git checkout HEAD^0 &&
git branch >actual &&
test_i18ncmp expect actual
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 3e0e15f..9b6f0d0 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -164,7 +164,7 @@ test_expect_success 'bisect start: existing ".git/BISECT_START" not modified if
cp .git/BISECT_START saved &&
test_must_fail git bisect start $HASH4 foo -- &&
git branch > branch.output &&
- test_i18ngrep "* (no branch)" branch.output > /dev/null &&
+ test_i18ngrep "* (no branch, bisecting other)" branch.output > /dev/null &&
test_cmp saved .git/BISECT_START
'
test_expect_success 'bisect start: no ".git/BISECT_START" if mistaken rev' '
--
1.8.1.2.536.gf441e6d
^ permalink raw reply related
* [PATCH v3 4/5] status: show more info than "currently not on any branch"
From: Nguyễn Thái Ngọc Duy @ 2013-03-13 11:42 UTC (permalink / raw)
To: git
Cc: Matthieu Moy, Jonathan Niedier, Junio C Hamano,
Nguyễn Thái Ngọc Duy
In-Reply-To: <1363174973-17597-1-git-send-email-pclouds@gmail.com>
When a remote ref or a tag is checked out, HEAD is automatically
detached. There is no user-friendly way to find out what ref is
checked out in this case. This patch digs in reflog for this
information and shows "HEAD detached from origin/master" or "HEAD
detached at v1.8.0" instead of "currently not on any branch".
When it cannot figure out the original ref, it shows an abbreviated
SHA-1. "Currently not on any branch" would never display (unless
reflog is pruned to near empty that the last checkout entry is lost).
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
t/t7406-submodule-update.sh | 6 ++-
t/t7512-status-help.sh | 52 ++++++++++++++++----------
wt-status.c | 89 +++++++++++++++++++++++++++++++++++++++++++--
wt-status.h | 4 +-
4 files changed, 125 insertions(+), 26 deletions(-)
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index ea61761..a4ffea0 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -665,8 +665,10 @@ test_expect_success 'submodule add properly re-creates deeper level submodules'
test_expect_success 'submodule update properly revives a moved submodule' '
(cd super &&
+ H=$(git rev-parse --short HEAD) &&
git commit -am "pre move" &&
- git status >expect&&
+ H2=$(git rev-parse --short HEAD) &&
+ git status | sed "s/$H/XXX/" >expect &&
H=$(cd submodule2; git rev-parse HEAD) &&
git rm --cached submodule2 &&
rm -rf submodule2 &&
@@ -675,7 +677,7 @@ test_expect_success 'submodule update properly revives a moved submodule' '
git config -f .gitmodules submodule.submodule2.path "moved/sub module"
git commit -am "post move" &&
git submodule update &&
- git status >actual &&
+ git status | sed "s/$H2/XXX/" >actual &&
test_cmp expect actual
)
'
diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
index d2da89a..da22088 100755
--- a/t/t7512-status-help.sh
+++ b/t/t7512-status-help.sh
@@ -76,7 +76,7 @@ test_expect_success 'status when rebase in progress before resolving conflicts'
ONTO=$(git rev-parse --short HEAD^^) &&
test_must_fail git rebase HEAD^ --onto HEAD^^ &&
cat >expected <<-EOF &&
- # Not currently on any branch.
+ # HEAD detached at $ONTO
# You are currently rebasing branch '\''rebase_conflicts'\'' on '\''$ONTO'\''.
# (fix conflicts and then run "git rebase --continue")
# (use "git rebase --skip" to skip this patch)
@@ -103,7 +103,7 @@ test_expect_success 'status when rebase in progress before rebase --continue' '
echo three >main.txt &&
git add main.txt &&
cat >expected <<-EOF &&
- # Not currently on any branch.
+ # HEAD detached at $ONTO
# You are currently rebasing branch '\''rebase_conflicts'\'' on '\''$ONTO'\''.
# (all conflicts fixed: run "git rebase --continue")
#
@@ -135,7 +135,7 @@ test_expect_success 'status during rebase -i when conflicts unresolved' '
ONTO=$(git rev-parse --short rebase_i_conflicts) &&
test_must_fail git rebase -i rebase_i_conflicts &&
cat >expected <<-EOF &&
- # Not currently on any branch.
+ # HEAD detached at $ONTO
# You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''$ONTO'\''.
# (fix conflicts and then run "git rebase --continue")
# (use "git rebase --skip" to skip this patch)
@@ -161,7 +161,7 @@ test_expect_success 'status during rebase -i after resolving conflicts' '
test_must_fail git rebase -i rebase_i_conflicts &&
git add main.txt &&
cat >expected <<-EOF &&
- # Not currently on any branch.
+ # HEAD detached at $ONTO
# You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''$ONTO'\''.
# (all conflicts fixed: run "git rebase --continue")
#
@@ -187,9 +187,10 @@ test_expect_success 'status when rebasing -i in edit mode' '
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
ONTO=$(git rev-parse --short HEAD~2) &&
+ TGT=$(git rev-parse --short two_rebase_i) &&
git rebase -i HEAD~2 &&
cat >expected <<-EOF &&
- # Not currently on any branch.
+ # HEAD detached from $TGT
# You are currently editing a commit while rebasing branch '\''rebase_i_edit'\'' on '\''$ONTO'\''.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
@@ -214,8 +215,9 @@ test_expect_success 'status when splitting a commit' '
ONTO=$(git rev-parse --short HEAD~3) &&
git rebase -i HEAD~3 &&
git reset HEAD^ &&
+ TGT=$(git rev-parse --short HEAD) &&
cat >expected <<-EOF &&
- # Not currently on any branch.
+ # HEAD detached at $TGT
# You are currently splitting a commit while rebasing branch '\''split_commit'\'' on '\''$ONTO'\''.
# (Once your working directory is clean, run "git rebase --continue")
#
@@ -243,10 +245,11 @@ test_expect_success 'status after editing the last commit with --amend during a
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
ONTO=$(git rev-parse --short HEAD~3) &&
+ TGT=$(git rev-parse --short three_amend) &&
git rebase -i HEAD~3 &&
git commit --amend -m "foo" &&
cat >expected <<-EOF &&
- # Not currently on any branch.
+ # HEAD detached from $TGT
# You are currently editing a commit while rebasing branch '\''amend_last'\'' on '\''$ONTO'\''.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
@@ -276,7 +279,7 @@ test_expect_success 'status: (continue first edit) second edit' '
git rebase -i HEAD~3 &&
git rebase --continue &&
cat >expected <<-EOF &&
- # Not currently on any branch.
+ # HEAD detached from $ONTO
# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
@@ -298,7 +301,7 @@ test_expect_success 'status: (continue first edit) second edit and split' '
git rebase --continue &&
git reset HEAD^ &&
cat >expected <<-EOF &&
- # Not currently on any branch.
+ # HEAD detached from $ONTO
# You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (Once your working directory is clean, run "git rebase --continue")
#
@@ -325,7 +328,7 @@ test_expect_success 'status: (continue first edit) second edit and amend' '
git rebase --continue &&
git commit --amend -m "foo" &&
cat >expected <<-EOF &&
- # Not currently on any branch.
+ # HEAD detached from $ONTO
# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
@@ -347,7 +350,7 @@ test_expect_success 'status: (amend first edit) second edit' '
git commit --amend -m "a" &&
git rebase --continue &&
cat >expected <<-EOF &&
- # Not currently on any branch.
+ # HEAD detached from $ONTO
# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
@@ -370,7 +373,7 @@ test_expect_success 'status: (amend first edit) second edit and split' '
git rebase --continue &&
git reset HEAD^ &&
cat >expected <<-EOF &&
- # Not currently on any branch.
+ # HEAD detached from $ONTO
# You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (Once your working directory is clean, run "git rebase --continue")
#
@@ -398,7 +401,7 @@ test_expect_success 'status: (amend first edit) second edit and amend' '
git rebase --continue &&
git commit --amend -m "d" &&
cat >expected <<-EOF &&
- # Not currently on any branch.
+ # HEAD detached from $ONTO
# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
@@ -422,7 +425,7 @@ test_expect_success 'status: (split first edit) second edit' '
git commit -m "e" &&
git rebase --continue &&
cat >expected <<-EOF &&
- # Not currently on any branch.
+ # HEAD detached from $ONTO
# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
@@ -447,7 +450,7 @@ test_expect_success 'status: (split first edit) second edit and split' '
git rebase --continue &&
git reset HEAD^ &&
cat >expected <<-EOF &&
- # Not currently on any branch.
+ # HEAD detached from $ONTO
# You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (Once your working directory is clean, run "git rebase --continue")
#
@@ -477,7 +480,7 @@ test_expect_success 'status: (split first edit) second edit and amend' '
git rebase --continue &&
git commit --amend -m "h" &&
cat >expected <<-EOF &&
- # Not currently on any branch.
+ # HEAD detached from $ONTO
# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
@@ -572,8 +575,9 @@ test_expect_success 'status when bisecting' '
git bisect start &&
git bisect bad &&
git bisect good one_bisect &&
- cat >expected <<-\EOF &&
- # Not currently on any branch.
+ TGT=$(git rev-parse --short two_bisect) &&
+ cat >expected <<-EOF &&
+ # HEAD detached at $TGT
# You are currently bisecting branch '\''bisect'\''.
# (use "git bisect reset" to get back to the original branch)
#
@@ -596,7 +600,7 @@ test_expect_success 'status when rebase conflicts with statushints disabled' '
ONTO=$(git rev-parse --short HEAD^^) &&
test_must_fail git rebase HEAD^ --onto HEAD^^ &&
cat >expected <<-EOF &&
- # Not currently on any branch.
+ # HEAD detached at $ONTO
# You are currently rebasing branch '\''statushints_disabled'\'' on '\''$ONTO'\''.
#
# Unmerged paths:
@@ -662,5 +666,15 @@ test_expect_success 'status when cherry-picking after resolving conflicts' '
test_i18ncmp expected actual
'
+test_expect_success 'status showing detached from a tag' '
+ test_commit atag tagging &&
+ git checkout atag &&
+ cat >expected <<-\EOF
+ # HEAD detached at atag
+ nothing to commit (use -u to show untracked files)
+ EOF
+ git status --untracked-files=no >actual &&
+ test_i18ncmp expected actual
+'
test_done
diff --git a/wt-status.c b/wt-status.c
index 17690d8..8c6e0c8 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -1001,7 +1001,73 @@ got_nothing:
return NULL;
}
-void wt_status_get_state(struct wt_status_state *state)
+struct grab_1st_switch_cbdata {
+ int found;
+ struct strbuf buf;
+ unsigned char nsha1[20];
+};
+
+static int grab_1st_switch(unsigned char *osha1, unsigned char *nsha1,
+ const char *email, unsigned long timestamp, int tz,
+ const char *message, void *cb_data)
+{
+ struct grab_1st_switch_cbdata *cb = cb_data;
+ const char *target = NULL, *end;
+
+ if (prefixcmp(message, "checkout: moving from "))
+ return 0;
+ message += strlen("checkout: moving from ");
+ target = strstr(message, " to ");
+ if (!target)
+ return 0;
+ target += strlen(" to ");
+ strbuf_reset(&cb->buf);
+ hashcpy(cb->nsha1, nsha1);
+ for (end = target; *end && *end != '\n'; end++)
+ ;
+ strbuf_add(&cb->buf, target, end - target);
+ cb->found = 1;
+ return 1;
+}
+
+static void wt_status_get_detached_from(struct wt_status_state *state)
+{
+ struct grab_1st_switch_cbdata cb;
+ struct commit *commit;
+ unsigned char sha1[20];
+ char *ref = NULL;
+
+ strbuf_init(&cb.buf, 0);
+ if (for_each_reflog_ent_reverse("HEAD", grab_1st_switch, &cb) <= 0) {
+ strbuf_release(&cb.buf);
+ return;
+ }
+
+ if (dwim_ref(cb.buf.buf, cb.buf.len, sha1, &ref) == 1 &&
+ /* sha1 is a commit? match without further lookup */
+ (!hashcmp(cb.nsha1, sha1) ||
+ /* perhaps sha1 is a tag, try to dereference to a commit */
+ ((commit = lookup_commit_reference_gently(sha1, 1)) != NULL &&
+ !hashcmp(cb.nsha1, commit->object.sha1)))) {
+ int ofs;
+ if (!prefixcmp(ref, "refs/tags/"))
+ ofs = strlen("refs/tags/");
+ else if (!prefixcmp(ref, "refs/remotes/"))
+ ofs = strlen("refs/remotes/");
+ else
+ ofs = 0;
+ state->detached_from = xstrdup(ref + ofs);
+ } else
+ state->detached_from =
+ xstrdup(find_unique_abbrev(cb.nsha1, DEFAULT_ABBREV));
+ hashcpy(state->detached_sha1, cb.nsha1);
+
+ free(ref);
+ strbuf_release(&cb.buf);
+}
+
+void wt_status_get_state(struct wt_status_state *state,
+ int get_detached_from)
{
struct stat st;
@@ -1031,6 +1097,9 @@ void wt_status_get_state(struct wt_status_state *state)
state->bisect_in_progress = 1;
state->branch = read_and_strip_branch("BISECT_START");
}
+
+ if (get_detached_from)
+ wt_status_get_detached_from(state);
}
static void wt_status_print_state(struct wt_status *s,
@@ -1056,7 +1125,8 @@ void wt_status_print(struct wt_status *s)
struct wt_status_state state;
memset(&state, 0, sizeof(state));
- wt_status_get_state(&state);
+ wt_status_get_state(&state,
+ s->branch && !strcmp(s->branch, "HEAD"));
if (s->branch) {
const char *on_what = _("On branch ");
@@ -1064,9 +1134,19 @@ void wt_status_print(struct wt_status *s)
if (!prefixcmp(branch_name, "refs/heads/"))
branch_name += 11;
else if (!strcmp(branch_name, "HEAD")) {
- branch_name = "";
branch_status_color = color(WT_STATUS_NOBRANCH, s);
- on_what = _("Not currently on any branch.");
+ if (state.detached_from) {
+ unsigned char sha1[20];
+ branch_name = state.detached_from;
+ if (!get_sha1("HEAD", sha1) &&
+ !hashcmp(sha1, state.detached_sha1))
+ on_what = _("HEAD detached at ");
+ else
+ on_what = _("HEAD detached from ");
+ } else {
+ branch_name = "";
+ on_what = _("Not currently on any branch.");
+ }
}
status_printf(s, color(WT_STATUS_HEADER, s), "");
status_printf_more(s, branch_status_color, "%s", on_what);
@@ -1078,6 +1158,7 @@ void wt_status_print(struct wt_status *s)
wt_status_print_state(s, &state);
free(state.branch);
free(state.onto);
+ free(state.detached_from);
if (s->is_initial) {
status_printf_ln(s, color(WT_STATUS_HEADER, s), "");
diff --git a/wt-status.h b/wt-status.h
index 5ddcbf6..5cb7df9 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -81,12 +81,14 @@ struct wt_status_state {
int bisect_in_progress;
char *branch;
char *onto;
+ char *detached_from;
+ unsigned char detached_sha1[20];
};
void wt_status_prepare(struct wt_status *s);
void wt_status_print(struct wt_status *s);
void wt_status_collect(struct wt_status *s);
-void wt_status_get_state(struct wt_status_state *state);
+void wt_status_get_state(struct wt_status_state *state, int get_detached_from);
void wt_shortstatus_print(struct wt_status *s);
void wt_porcelain_print(struct wt_status *s);
--
1.8.1.2.536.gf441e6d
^ permalink raw reply related
* [PATCH v3 3/5] wt-status: move wt_status_get_state() out to wt_status_print()
From: Nguyễn Thái Ngọc Duy @ 2013-03-13 11:42 UTC (permalink / raw)
To: git
Cc: Matthieu Moy, Jonathan Niedier, Junio C Hamano,
Nguyễn Thái Ngọc Duy
In-Reply-To: <1363174973-17597-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
wt-status.c | 39 ++++++++++++++++++++-------------------
1 file changed, 20 insertions(+), 19 deletions(-)
diff --git a/wt-status.c b/wt-status.c
index 0d8989f..17690d8 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -1033,32 +1033,30 @@ void wt_status_get_state(struct wt_status_state *state)
}
}
-static void wt_status_print_state(struct wt_status *s)
+static void wt_status_print_state(struct wt_status *s,
+ struct wt_status_state *state)
{
const char *state_color = color(WT_STATUS_HEADER, s);
- struct wt_status_state state;
-
- memset(&state, 0, sizeof(state));
- wt_status_get_state(&state);
-
- if (state.merge_in_progress)
- show_merge_in_progress(s, &state, state_color);
- else if (state.am_in_progress)
- show_am_in_progress(s, &state, state_color);
- else if (state.rebase_in_progress || state.rebase_interactive_in_progress)
- show_rebase_in_progress(s, &state, state_color);
- else if (state.cherry_pick_in_progress)
- show_cherry_pick_in_progress(s, &state, state_color);
- if (state.bisect_in_progress)
- show_bisect_in_progress(s, &state, state_color);
- free(state.branch);
- free(state.onto);
+ if (state->merge_in_progress)
+ show_merge_in_progress(s, state, state_color);
+ else if (state->am_in_progress)
+ show_am_in_progress(s, state, state_color);
+ else if (state->rebase_in_progress || state->rebase_interactive_in_progress)
+ show_rebase_in_progress(s, state, state_color);
+ else if (state->cherry_pick_in_progress)
+ show_cherry_pick_in_progress(s, state, state_color);
+ if (state->bisect_in_progress)
+ show_bisect_in_progress(s, state, state_color);
}
void wt_status_print(struct wt_status *s)
{
const char *branch_color = color(WT_STATUS_ONBRANCH, s);
const char *branch_status_color = color(WT_STATUS_HEADER, s);
+ struct wt_status_state state;
+
+ memset(&state, 0, sizeof(state));
+ wt_status_get_state(&state);
if (s->branch) {
const char *on_what = _("On branch ");
@@ -1077,7 +1075,10 @@ void wt_status_print(struct wt_status *s)
wt_status_print_tracking(s);
}
- wt_status_print_state(s);
+ wt_status_print_state(s, &state);
+ free(state.branch);
+ free(state.onto);
+
if (s->is_initial) {
status_printf_ln(s, color(WT_STATUS_HEADER, s), "");
status_printf_ln(s, color(WT_STATUS_HEADER, s), _("Initial commit"));
--
1.8.1.2.536.gf441e6d
^ permalink raw reply related
* [PATCH v3 2/5] wt-status: split wt_status_state parsing function out
From: Nguyễn Thái Ngọc Duy @ 2013-03-13 11:42 UTC (permalink / raw)
To: git
Cc: Matthieu Moy, Jonathan Niedier, Junio C Hamano,
Nguyễn Thái Ngọc Duy
In-Reply-To: <1363174973-17597-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
wt-status.c | 41 +++++++++++++++++++++++------------------
wt-status.h | 1 +
2 files changed, 24 insertions(+), 18 deletions(-)
diff --git a/wt-status.c b/wt-status.c
index 6cac27b..0d8989f 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -1001,40 +1001,45 @@ got_nothing:
return NULL;
}
-static void wt_status_print_state(struct wt_status *s)
+void wt_status_get_state(struct wt_status_state *state)
{
- const char *state_color = color(WT_STATUS_HEADER, s);
- struct wt_status_state state;
struct stat st;
- memset(&state, 0, sizeof(state));
-
if (!stat(git_path("MERGE_HEAD"), &st)) {
- state.merge_in_progress = 1;
+ state->merge_in_progress = 1;
} else if (!stat(git_path("rebase-apply"), &st)) {
if (!stat(git_path("rebase-apply/applying"), &st)) {
- state.am_in_progress = 1;
+ state->am_in_progress = 1;
if (!stat(git_path("rebase-apply/patch"), &st) && !st.st_size)
- state.am_empty_patch = 1;
+ state->am_empty_patch = 1;
} else {
- state.rebase_in_progress = 1;
- state.branch = read_and_strip_branch("rebase-apply/head-name");
- state.onto = read_and_strip_branch("rebase-apply/onto");
+ state->rebase_in_progress = 1;
+ state->branch = read_and_strip_branch("rebase-apply/head-name");
+ state->onto = read_and_strip_branch("rebase-apply/onto");
}
} else if (!stat(git_path("rebase-merge"), &st)) {
if (!stat(git_path("rebase-merge/interactive"), &st))
- state.rebase_interactive_in_progress = 1;
+ state->rebase_interactive_in_progress = 1;
else
- state.rebase_in_progress = 1;
- state.branch = read_and_strip_branch("rebase-merge/head-name");
- state.onto = read_and_strip_branch("rebase-merge/onto");
+ state->rebase_in_progress = 1;
+ state->branch = read_and_strip_branch("rebase-merge/head-name");
+ state->onto = read_and_strip_branch("rebase-merge/onto");
} else if (!stat(git_path("CHERRY_PICK_HEAD"), &st)) {
- state.cherry_pick_in_progress = 1;
+ state->cherry_pick_in_progress = 1;
}
if (!stat(git_path("BISECT_LOG"), &st)) {
- state.bisect_in_progress = 1;
- state.branch = read_and_strip_branch("BISECT_START");
+ state->bisect_in_progress = 1;
+ state->branch = read_and_strip_branch("BISECT_START");
}
+}
+
+static void wt_status_print_state(struct wt_status *s)
+{
+ const char *state_color = color(WT_STATUS_HEADER, s);
+ struct wt_status_state state;
+
+ memset(&state, 0, sizeof(state));
+ wt_status_get_state(&state);
if (state.merge_in_progress)
show_merge_in_progress(s, &state, state_color);
diff --git a/wt-status.h b/wt-status.h
index b8c3512..5ddcbf6 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -86,6 +86,7 @@ struct wt_status_state {
void wt_status_prepare(struct wt_status *s);
void wt_status_print(struct wt_status *s);
void wt_status_collect(struct wt_status *s);
+void wt_status_get_state(struct wt_status_state *state);
void wt_shortstatus_print(struct wt_status *s);
void wt_porcelain_print(struct wt_status *s);
--
1.8.1.2.536.gf441e6d
^ permalink raw reply related
* [PATCH v3 1/5] wt-status: move strbuf into read_and_strip_branch()
From: Nguyễn Thái Ngọc Duy @ 2013-03-13 11:42 UTC (permalink / raw)
To: git
Cc: Matthieu Moy, Jonathan Niedier, Junio C Hamano,
Nguyễn Thái Ngọc Duy
In-Reply-To: <1363174973-17597-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
wt-status.c | 65 ++++++++++++++++++++++++++++---------------------------------
wt-status.h | 4 ++--
2 files changed, 32 insertions(+), 37 deletions(-)
diff --git a/wt-status.c b/wt-status.c
index ef405d0..6cac27b 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -969,41 +969,41 @@ static void show_bisect_in_progress(struct wt_status *s,
/*
* Extract branch information from rebase/bisect
*/
-static void read_and_strip_branch(struct strbuf *sb,
- const char **branch,
- const char *path)
+static char *read_and_strip_branch(const char *path)
{
+ struct strbuf sb = STRBUF_INIT;
unsigned char sha1[20];
- strbuf_reset(sb);
- if (strbuf_read_file(sb, git_path("%s", path), 0) <= 0)
- return;
+ if (strbuf_read_file(&sb, git_path("%s", path), 0) <= 0)
+ goto got_nothing;
- while (sb->len && sb->buf[sb->len - 1] == '\n')
- strbuf_setlen(sb, sb->len - 1);
- if (!sb->len)
- return;
- if (!prefixcmp(sb->buf, "refs/heads/"))
- *branch = sb->buf + strlen("refs/heads/");
- else if (!prefixcmp(sb->buf, "refs/"))
- *branch = sb->buf;
- else if (!get_sha1_hex(sb->buf, sha1)) {
+ while (&sb.len && sb.buf[sb.len - 1] == '\n')
+ strbuf_setlen(&sb, sb.len - 1);
+ if (!sb.len)
+ goto got_nothing;
+ if (!prefixcmp(sb.buf, "refs/heads/"))
+ strbuf_remove(&sb,0, strlen("refs/heads/"));
+ else if (!prefixcmp(sb.buf, "refs/"))
+ ;
+ else if (!get_sha1_hex(sb.buf, sha1)) {
const char *abbrev;
abbrev = find_unique_abbrev(sha1, DEFAULT_ABBREV);
- strbuf_reset(sb);
- strbuf_addstr(sb, abbrev);
- *branch = sb->buf;
- } else if (!strcmp(sb->buf, "detached HEAD")) /* rebase */
- ;
+ strbuf_reset(&sb);
+ strbuf_addstr(&sb, abbrev);
+ } else if (!strcmp(sb.buf, "detached HEAD")) /* rebase */
+ goto got_nothing;
else /* bisect */
- *branch = sb->buf;
+ ;
+ return strbuf_detach(&sb, NULL);
+
+got_nothing:
+ strbuf_release(&sb);
+ return NULL;
}
static void wt_status_print_state(struct wt_status *s)
{
const char *state_color = color(WT_STATUS_HEADER, s);
- struct strbuf branch = STRBUF_INIT;
- struct strbuf onto = STRBUF_INIT;
struct wt_status_state state;
struct stat st;
@@ -1018,27 +1018,22 @@ static void wt_status_print_state(struct wt_status *s)
state.am_empty_patch = 1;
} else {
state.rebase_in_progress = 1;
- read_and_strip_branch(&branch, &state.branch,
- "rebase-apply/head-name");
- read_and_strip_branch(&onto, &state.onto,
- "rebase-apply/onto");
+ state.branch = read_and_strip_branch("rebase-apply/head-name");
+ state.onto = read_and_strip_branch("rebase-apply/onto");
}
} else if (!stat(git_path("rebase-merge"), &st)) {
if (!stat(git_path("rebase-merge/interactive"), &st))
state.rebase_interactive_in_progress = 1;
else
state.rebase_in_progress = 1;
- read_and_strip_branch(&branch, &state.branch,
- "rebase-merge/head-name");
- read_and_strip_branch(&onto, &state.onto,
- "rebase-merge/onto");
+ state.branch = read_and_strip_branch("rebase-merge/head-name");
+ state.onto = read_and_strip_branch("rebase-merge/onto");
} else if (!stat(git_path("CHERRY_PICK_HEAD"), &st)) {
state.cherry_pick_in_progress = 1;
}
if (!stat(git_path("BISECT_LOG"), &st)) {
state.bisect_in_progress = 1;
- read_and_strip_branch(&branch, &state.branch,
- "BISECT_START");
+ state.branch = read_and_strip_branch("BISECT_START");
}
if (state.merge_in_progress)
@@ -1051,8 +1046,8 @@ static void wt_status_print_state(struct wt_status *s)
show_cherry_pick_in_progress(s, &state, state_color);
if (state.bisect_in_progress)
show_bisect_in_progress(s, &state, state_color);
- strbuf_release(&branch);
- strbuf_release(&onto);
+ free(state.branch);
+ free(state.onto);
}
void wt_status_print(struct wt_status *s)
diff --git a/wt-status.h b/wt-status.h
index 81e1dcf..b8c3512 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -79,8 +79,8 @@ struct wt_status_state {
int rebase_interactive_in_progress;
int cherry_pick_in_progress;
int bisect_in_progress;
- const char *branch;
- const char *onto;
+ char *branch;
+ char *onto;
};
void wt_status_prepare(struct wt_status *s);
--
1.8.1.2.536.gf441e6d
^ permalink raw reply related
* [PATCH v3 0/5] nd/branch-show-rebase-bisect-state updates
From: Nguyễn Thái Ngọc Duy @ 2013-03-13 11:42 UTC (permalink / raw)
To: git
Cc: Matthieu Moy, Jonathan Niedier, Junio C Hamano,
Nguyễn Thái Ngọc Duy
In-Reply-To: <1362572482-20570-1-git-send-email-pclouds@gmail.com>
This round fixes the design issue of read_and_strip_branch(), makes
use of jc/reflog-reverse-walk and performs cheaper sha-1 check on
detached commits.
Nguyễn Thái Ngọc Duy (5):
wt-status: move strbuf into read_and_strip_branch()
wt-status: split wt_status_state parsing function out
wt-status: move wt_status_get_state() out to wt_status_print()
status: show more info than "currently not on any branch"
branch: show more information when HEAD is detached
builtin/branch.c | 26 +++++-
t/t3203-branch-output.sh | 6 +-
t/t6030-bisect-porcelain.sh | 2 +-
t/t7406-submodule-update.sh | 6 +-
t/t7512-status-help.sh | 52 ++++++-----
wt-status.c | 204 +++++++++++++++++++++++++++++++-------------
wt-status.h | 7 +-
7 files changed, 214 insertions(+), 89 deletions(-)
--
1.8.1.2.536.gf441e6d
^ permalink raw reply
* Re: [PATCH 2/2] add: respect add.updateroot config option
From: Jeff King @ 2013-03-13 9:27 UTC (permalink / raw)
To: Matthieu Moy; +Cc: Junio C Hamano, git, David Aguilar
In-Reply-To: <vpqr4jjd5wp.fsf@grenoble-inp.fr>
On Wed, Mar 13, 2013 at 10:07:34AM +0100, Matthieu Moy wrote:
> Jeff King <peff@peff.net> writes:
>
> > For users who have read and accepted the warning, there is no way to
> > jump directly to the future behavior and silence the warning.
>
> I think the idea makes sense. The transition period is necessary for
> people who use different versions of Git (which includes anybody
> writting and distributing scripts), but for poor mortals who only use a
> single version of Git, it's nice to be able to jump to the future
> behavior once for all as soon as possible.
I think the biggest risk is from people who think they are safe to jump,
and then find out that some script they depend on is not ready. Even if
they do not even realize they are relying on it. Part of the point of
the transition period is to get script authors to update their scripts,
and to let the new versions trickle down to the users.
> Your patch doesn't advertise the option in the warning message, which I
> think is good. You may mention it the commit message that this is a
> deliberate choice.
Yes, it was deliberate. I can add a note.
> > +add.updateroot::
>
> Detail: option names are normally camelCased => updateRoot.
Good point, thanks.
> I think the option name needs a bit more thinking. Without reading the
> doc,
>
> [add]
> updateRoot = false
>
> would be a very tempting thing to try. Perhaps explicitly warning when
> add.updateroot is set to false would avoid possible confusion.
Yeah, that occurred to me, too, hence the note in the doc. Since it
isn't advertised elsewhere, I had hoped that anybody who discovered it
would see the note. I suppose we can warn when we see add.updateRoot set
to anything but true. That feels a bit hacky, as it's possible the user
could be overriding an earlier setting (although that is getting kind of
crazy).
> I liked David's suggestion of using future.* to mean "start using
> behavior from the future right now".
I do like that idea, as it makes the meaning of the variable more clear.
I dunno. I am not all that excited about this patch, due to all of the
caveats that we need to communicate to the user. The current warning has
annoyed me a few times, but perhaps it is still too soon, and my fingers
and brain just need retraining. I think a config option could help some
people, but maybe it will end up hurting more. I'm inclined at this
point to table the patch for now and see how I feel in a few weeks.
I do think patch 1/2 makes sense regardless.
-Peff
^ permalink raw reply
* Re: [PATCH] tag: --force is quiet about new tags
From: Michael J Gruber @ 2013-03-13 9:16 UTC (permalink / raw)
To: Phil Hord; +Cc: Junio C Hamano, Phil Hord, git@vger.kernel.org
In-Reply-To: <CABURp0oT8ZN5fKtKh67Gm1P5rf_a3diqcYbw8mUga-gv5MPu6Q@mail.gmail.com>
Phil Hord venit, vidit, dixit 13.03.2013 05:21:
> On Tue, Mar 12, 2013 at 11:33 PM, Junio C Hamano <gitster@pobox.com> wrote:
>> Phil Hord <hordp@cisco.com> writes:
>>
>>> git tag --force is used to replace an existing tag with
>>> a new reference. Git helpfully tells the user the old
>>> ref when this happens. But if the tag name is new and does
>>> not exist, git tells the user the old ref anyway (000000).
>>>
>>> Teach git to ignore --force if the tag is new. Add a test
>>> for this and also to ensure --force can replace tags at all.
>>>
>>> Signed-off-by: Phil Hord <hordp@cisco.com>
>>> ---
>>
>> I think we would still want to allow the operation to go through,
>> even when the --force option is given, to create a new tag. I agree
>> that the message should not say "Updated". So teaching Git not to
>> issue the "Updated" message makes perfect sense. It is somewhat
>> misleading to say we are teaching Git to ignore the option, though.
>>
>> Thanks.
>
> My phrasing was too ambiguous. What you described is exactly what the
> patch does. --force is superfluous when the tag does not already
> exist. It is only checked in two places, and one of those is to
> decide whether to print the "Updated" message. How's this?
>
> Teach 'git tag --force' to suppress the update message if
> the tag is new. Add a test for this and also to ensure
> --force can replace tags at all.
>
> Phil
Looks good to me, both the patch and the (updated) commit message.
Michael
^ permalink raw reply
* Re: [PATCH] difftool: Make directory diff symlink work tree
From: John Keeping @ 2013-03-13 9:11 UTC (permalink / raw)
To: Matt McClure; +Cc: David Aguilar, git@vger.kernel.org, Tim Henigan
In-Reply-To: <CAJELnLEmrBSiua3xe_Y7MS1SCL8TD28sQH-R6Kfn9Zk+Zm6=kw@mail.gmail.com>
On Tue, Mar 12, 2013 at 08:26:21PM -0400, Matt McClure wrote:
> On Tue, Mar 12, 2013 at 3:24 PM, John Keeping <john@keeping.me.uk> wrote:
> > If so I think you want some new mode of operation for difftool instead
> > of this patch which will also affect unrelated commands.
>
> Are you suggesting that difftool do the reset work above given a new
> option or by default?
I was suggesting something like the "--symlink-all" option discussed in
the parallel thread, but it looks like we now have a better solution
than that.
John
^ permalink raw reply
* Re: [PATCH 2/2] add: respect add.updateroot config option
From: Matthieu Moy @ 2013-03-13 9:07 UTC (permalink / raw)
To: Jeff King; +Cc: Junio C Hamano, git, David Aguilar
In-Reply-To: <20130313041037.GB5378@sigill.intra.peff.net>
Jeff King <peff@peff.net> writes:
> For users who have read and accepted the warning, there is no way to
> jump directly to the future behavior and silence the warning.
I think the idea makes sense. The transition period is necessary for
people who use different versions of Git (which includes anybody
writting and distributing scripts), but for poor mortals who only use a
single version of Git, it's nice to be able to jump to the future
behavior once for all as soon as possible.
Your patch doesn't advertise the option in the warning message, which I
think is good. You may mention it the commit message that this is a
deliberate choice.
> +add.updateroot::
Detail: option names are normally camelCased => updateRoot.
I think the option name needs a bit more thinking. Without reading the
doc,
[add]
updateRoot = false
would be a very tempting thing to try. Perhaps explicitly warning when
add.updateroot is set to false would avoid possible confusion.
In case you had missed it, here's a previous piece of discussion on the
subject:
http://thread.gmane.org/gmane.comp.version-control.git/216818/focus=216846
I liked David's suggestion of using future.* to mean "start using
behavior from the future right now".
> + which they were called. In a future version of git, this behavior
Capital "Git".
--
Matthieu Moy
http://www-verimag.imag.fr/~moy/
^ permalink raw reply
* Re: [PATCH v3 3/3] git-merge-one-file: revise merge error reporting
From: David Aguilar @ 2013-03-13 9:03 UTC (permalink / raw)
To: Kevin Bracey; +Cc: git, Ciaran Jessup, Scott Chacon, Alex Riesen
In-Reply-To: <1363137142-18606-3-git-send-email-kevin@bracey.fi>
On Tue, Mar 12, 2013 at 6:12 PM, Kevin Bracey <kevin@bracey.fi> wrote:
> Commit 718135e improved the merge error reporting for the resolve
> strategy's merge conflict and permission conflict cases, but led to a
> malformed "ERROR: in myfile.c" message in the case of a file added
> differently.
>
> This commit reverts that change, and uses an alternative approach without
> this flaw.
>
> Signed-off-by: Kevin Bracey <kevin@bracey.fi>
> ---
I wonder whether before these changes we should
update the style in this file to follow Documentation/CodingGuidelines.
Not in this patch, but in the file right now there's
this part that stands out:
if [ "$2" ]; then
echo "Removing $4"
I think that expression would read more clearly as:
if test -n "$2"
then
echo "Removing $4"
Ditto `if [ "$1" = '' ]` is better written as `test -z "$1"`.
Can you please send a patch to true these up?
It'd be especially nice if the style patch could come
first, followed by the fixes/features ;-)
> git-merge-one-file.sh | 20 +++++++-------------
> 1 file changed, 7 insertions(+), 13 deletions(-)
>
> diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh
> index 0f164e5..78b07a8 100755
> --- a/git-merge-one-file.sh
> +++ b/git-merge-one-file.sh
> @@ -104,11 +104,13 @@ case "${1:-.}${2:-.}${3:-.}" in
> ;;
> esac
>
> + ret=0
> src1=$(git-unpack-file $2)
> src2=$(git-unpack-file $3)
> case "$1" in
> '')
> - echo "Added $4 in both, but differently."
> + echo "ERROR: Added $4 in both, but differently."
> + ret=1
> orig=$(git-unpack-file $2)
> create_virtual_base "$orig" "$src2"
> ;;
> @@ -121,10 +123,9 @@ case "${1:-.}${2:-.}${3:-.}" in
> # Be careful for funny filename such as "-L" in "$4", which
> # would confuse "merge" greatly.
> git merge-file "$src1" "$orig" "$src2"
> - ret=$?
> - msg=
> - if [ $ret -ne 0 ]; then
> - msg='content conflict'
> + if [ $? -ne 0 ]; then
> + echo "ERROR: Content conflict in $4"
> + ret=1
if test $? != 0
then
Also.. should this error not go to stderr?
I guess the existing script was not doing that,
but it seems like anything that says "ERROR" should go there.
> fi
>
> # Create the working tree file, using "our tree" version from the
> @@ -133,18 +134,11 @@ case "${1:-.}${2:-.}${3:-.}" in
> rm -f -- "$orig" "$src1" "$src2"
>
> if [ "$6" != "$7" ]; then
> - if [ -n "$msg" ]; then
> - msg="$msg, "
> - fi
> - msg="${msg}permissions conflict: $5->$6,$7"
> - ret=1
> - fi
> - if [ "$1" = '' ]; then
> + echo "ERROR: Permissions conflict: $5->$6,$7"
> ret=1
> fi
>
> if [ $ret -ne 0 ]; then
> - echo "ERROR: $msg in $4"
> exit 1
> fi
> exec git update-index -- "$4"
same notes as above. I think a style patch should come first.
--
David
^ permalink raw reply
* Re: [PATCH 1/2] t2200: check that "add -u" limits itself to subdirectory
From: Matthieu Moy @ 2013-03-13 8:52 UTC (permalink / raw)
To: Jeff King; +Cc: Junio C Hamano, git
In-Reply-To: <20130313041022.GA5378@sigill.intra.peff.net>
Jeff King <peff@peff.net> writes:
> This behavior is due to change in the future, but let's test
> it anyway.
Thanks. This should be merged regardless of PATCH 2/2 I think.
--
Matthieu Moy
http://www-verimag.imag.fr/~moy/
^ permalink raw reply
* Re: difftool -d symlinks, under what conditions
From: David Aguilar @ 2013-03-13 8:24 UTC (permalink / raw)
To: John Keeping
Cc: Matt McClure, Junio C Hamano, git@vger.kernel.org, Tim Henigan
In-Reply-To: <20130313001758.GH2317@serenity.lan>
On Tue, Mar 12, 2013 at 5:17 PM, John Keeping <john@keeping.me.uk> wrote:
> On Tue, Mar 12, 2013 at 04:48:16PM -0600, Matt McClure wrote:
>> On Mar 12, 2013, at 4:16 PM, Junio C Hamano <gitster@pobox.com> wrote:
>>
>> > Matt McClure <matthewlmcclure@gmail.com> writes:
>> >
>> > * If you are comparing two trees, and especially if your RHS is not
>> > HEAD, you will send everything to a temporary without
>> > symlinks. Any edit made by the user will be lost.
>>
>> I think you're suggesting to use a symlink any time the content of any
>> given RHS revision is the same as the working tree.
>>
>> I imagine that might confuse me as a user. It would create
>> circumstances where some files are symlinked and others aren't for
>> reasons that won't be straightforward.
>>
>> I imagine solving that case, I might instead implement a copy back to
>> the working tree with conflict detection/resolution. Some earlier
>> iterations of the directory diff feature used copy back without
>> conflict detection and created situations where I clobbered my own
>> changes by finishing a directory diff after making edits concurrently.
>
> The code to copy back working tree files is already there, it just
> triggers using the same logic as the creation of symlinks in the first
> place and doesn't attempt any conflict detection. I suspect that any
> more comprehensive solution will need to restrict the use of "git
> difftool -d" whenever the index contains unmerged entries or when there
> are both staged and unstaged changes, since the merge resolution will
> cause these states to be lost.
>
> The implementation of Junio's suggestion is relatively straightforward
> (this is untested, although t7800 passes, and can probably be improved
> by someone better versed in Perl). Does this work for your original
> scenario?
This is a nice straightforward approach.
As Junio mentioned, a good next step would be this patch
in combination with making the truly temporary files
created by dir-diff readonly.
Will that need a win32 platform check?
Does anyone want to take this and whip it into a proper patch?
> -- >8 --
> diff --git a/git-difftool.perl b/git-difftool.perl
> index 0a90de4..5f093ae 100755
> --- a/git-difftool.perl
> +++ b/git-difftool.perl
> @@ -83,6 +83,21 @@ sub exit_cleanup
> exit($status | ($status >> 8));
> }
>
> +sub use_wt_file
> +{
> + my ($repo, $workdir, $file, $sha1, $symlinks) = @_;
> + my $null_sha1 = '0' x 40;
> +
> + if ($sha1 eq $null_sha1) {
> + return 1;
> + } elsif (not $symlinks) {
> + return 0;
> + }
> +
> + my $wt_sha1 = $repo->command_oneline('hash-object', "$workdir/$file");
> + return $sha1 eq $wt_sha1;
> +}
> +
> sub setup_dir_diff
> {
> my ($repo, $workdir, $symlinks) = @_;
> @@ -159,10 +174,10 @@ EOF
> }
>
> if ($rmode ne $null_mode) {
> - if ($rsha1 ne $null_sha1) {
> - $rindex .= "$rmode $rsha1\t$dst_path\0";
> - } else {
> + if (use_wt_file($repo, $workdir, $dst_path, $rsha1, $symlinks)) {
> push(@working_tree, $dst_path);
> + } else {
> + $rindex .= "$rmode $rsha1\t$dst_path\0";
> }
> }
> }
> --
> 1.8.2.rc2.4.g7799588
>
--
David
^ permalink raw reply
* Re: [PATCH v8 2/5] blame: introduce $ as "end of file" in -L syntax
From: Thomas Rast @ 2013-03-13 7:52 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Bo Yang, Zbigniew Jędrzejewski-Szmek, Will Palmer
In-Reply-To: <7va9q85jt9.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> Junio C Hamano <gitster@pobox.com> writes:
>
>> Thomas Rast <trast@student.ethz.ch> writes:
>>
>>> To save the user a lookup of the last line number, introduce $ as a
>>> shorthand for the last line. This is mostly useful to spell "until
>>> the end of the file" as '-L<begin>,$'.
>>
>> Doesn't "-L <begin>" or "-L <begin>," do that already? If it were
>> to introduce "-L $-4," or "-L$-4,+2", I would understand why the
>> addition may be useful, but otherwise I do not think it adds much
>> value.
>
> It is a quiet-period so there is no need to rush, but did anything
> happened further on this series?
No, I've been busy :-(
The only open point is in the other email:
> >> Documentation/blame-options.txt | 19 +------
> >> Documentation/line-range-format.txt | 18 +++++++
> >> Makefile | 2 +
> >> builtin/blame.c | 99 +++-------------------------------
> >> line-log.c | 105 ++++++++++++++++++++++++++++++++++++
> >> line-log.h | 23 ++++++++
> >
> > Was this churn necessary?
> >
> > It is strange to move existing functions that will be tweaked to be
> > shared by two different codepaths (blame and line-log) to the new
> > user.
> [...]
>
> Even though I am moving from builtin/blame.c to line-log.c? I would
> otherwise have to call from a rather lib-ish file into a "front
You haven't sent any reply to this. Does that mean you agree? Would
you prefer the shared file to be named something like line-range.c?
--
Thomas Rast
trast@{inf,student}.ethz.ch
^ permalink raw reply
* Re: [PATCH] tag: --force is quiet about new tags
From: Phil Hord @ 2013-03-13 4:21 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Phil Hord, git@vger.kernel.org, Michael J Gruber
In-Reply-To: <7vy5ds3re0.fsf@alter.siamese.dyndns.org>
On Tue, Mar 12, 2013 at 11:33 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Phil Hord <hordp@cisco.com> writes:
>
>> git tag --force is used to replace an existing tag with
>> a new reference. Git helpfully tells the user the old
>> ref when this happens. But if the tag name is new and does
>> not exist, git tells the user the old ref anyway (000000).
>>
>> Teach git to ignore --force if the tag is new. Add a test
>> for this and also to ensure --force can replace tags at all.
>>
>> Signed-off-by: Phil Hord <hordp@cisco.com>
>> ---
>
> I think we would still want to allow the operation to go through,
> even when the --force option is given, to create a new tag. I agree
> that the message should not say "Updated". So teaching Git not to
> issue the "Updated" message makes perfect sense. It is somewhat
> misleading to say we are teaching Git to ignore the option, though.
>
> Thanks.
My phrasing was too ambiguous. What you described is exactly what the
patch does. --force is superfluous when the tag does not already
exist. It is only checked in two places, and one of those is to
decide whether to print the "Updated" message. How's this?
Teach 'git tag --force' to suppress the update message if
the tag is new. Add a test for this and also to ensure
--force can replace tags at all.
Phil
^ permalink raw reply
* [PATCH 2/2] add: respect add.updateroot config option
From: Jeff King @ 2013-03-13 4:10 UTC (permalink / raw)
To: Matthieu Moy; +Cc: Junio C Hamano, git
In-Reply-To: <20130313040845.GA5057@sigill.intra.peff.net>
The `git add -u` command operates on the current subdir of
the repository, but is transitioning to operate on the whole
repository (see commit 0fa2eb5 for details). During the
transition period, we issue a warning. For users who have
read and accepted the warning, there is no way to jump
directly to the future behavior and silence the warning. The
config option added by this patch gives them such an option.
Signed-off-by: Jeff King <peff@peff.net>
---
Documentation/config.txt | 19 +++++++++++++++++++
builtin/add.c | 10 ++++++++--
t/t2200-add-update.sh | 14 ++++++++++++++
3 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index bbba728..be0f6fc 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -657,6 +657,25 @@ add.ignoreErrors::
convention for configuration variables. Newer versions of Git
honor `add.ignoreErrors` as well.
+add.updateroot::
+ Historically, when the `git add -u` and `git add -A` commands
+ are run from a subdirectory of the repository and are not given
+ any pathspec, they have operated only on the subdirectory from
+ which they were called. In a future version of git, this behavior
+ will be switched to operate on the full repository instead. In
+ the meantime, issuing `git add -u` (or `-A`) from a subdirectory
+ continues to work on the subdirectory, but will now issue a
+ warning. If you are ready to move to the new behavior now,
+ accepting that you may be breaking existing scripts which expect
+ the old behavior, you can do so by setting `add.updateroot` to
+ `true`.
++
+Note that this is meant to let early adopters move to the new behavior
+immediately; it is not a toggle switch that will work forever. After
+git transitions to the new behavior, this option will become a no-op;
+`git add -u` will always update the whole tree, and `git add -u .` will
+remain the correct way to limit to the current directory.
+
alias.*::
Command aliases for the linkgit:git[1] command wrapper - e.g.
after defining "alias.last = cat-file commit HEAD", the invocation
diff --git a/builtin/add.c b/builtin/add.c
index ab1c9e8..95fe35e 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -22,6 +22,7 @@ static int take_worktree_changes;
};
static int patch_interactive, add_interactive, edit_interactive;
static int take_worktree_changes;
+static int update_root;
struct update_callback_data {
int flags;
@@ -297,6 +298,10 @@ static int add_config(const char *var, const char *value, void *cb)
ignore_add_errors = git_config_bool(var, value);
return 0;
}
+ if (!strcmp(var, "add.updateroot")) {
+ update_root = git_config_bool(var, value);
+ return 0;
+ }
return git_default_config(var, value, cb);
}
@@ -390,12 +395,13 @@ int cmd_add(int argc, const char **argv, const char *prefix)
short_option_with_implicit_dot = "-u";
}
if (option_with_implicit_dot && !argc) {
+ static const char *root[2] = { ":/", NULL };
static const char *here[2] = { ".", NULL };
- if (prefix)
+ if (!update_root && prefix)
warn_pathless_add(option_with_implicit_dot,
short_option_with_implicit_dot);
argc = 1;
- argv = here;
+ argv = update_root ? root : here;
}
add_new_files = !take_worktree_changes && !refresh_only;
diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh
index fe4f548..b9215d3 100755
--- a/t/t2200-add-update.sh
+++ b/t/t2200-add-update.sh
@@ -91,6 +91,20 @@ test_expect_success 'update did not touch files at root' '
test_cmp expect actual
'
+test_expect_success 'update with add.updateroot set' '
+ (
+ cd dir1 &&
+ echo more >>sub2 &&
+ git -c add.updateroot=true add -u
+ )
+'
+
+test_expect_success 'all paths are updated' '
+ >expect &&
+ git diff-files --name-status >actual &&
+ test_cmp expect actual
+'
+
test_expect_success SYMLINKS 'replace a file with a symlink' '
rm foo &&
--
1.8.2.rc2.7.gef06216
^ permalink raw reply related
* [PATCH 1/2] t2200: check that "add -u" limits itself to subdirectory
From: Jeff King @ 2013-03-13 4:10 UTC (permalink / raw)
To: Matthieu Moy; +Cc: Junio C Hamano, git
In-Reply-To: <20130313040845.GA5057@sigill.intra.peff.net>
This behavior is due to change in the future, but let's test
it anyway. That helps make sure we do not accidentally
switch the behavior too soon while we are working in the
area, and it means that we can easily verify the change when
we do make it.
Signed-off-by: Jeff King <peff@peff.net>
---
We didn't seem to be testing this transition at all. I think it's sane
to do so now, and Junio's "now it is 2.0, let's switch" patch should
update the test.
t/t2200-add-update.sh | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh
index 4cdebda..fe4f548 100755
--- a/t/t2200-add-update.sh
+++ b/t/t2200-add-update.sh
@@ -80,6 +80,17 @@ test_expect_success 'change gets noticed' '
'
+# Note that this is scheduled to change in Git 2.0, when
+# "git add -u" will become full-tree by default.
+test_expect_success 'update did not touch files at root' '
+ cat >expect <<-\EOF &&
+ check
+ top
+ EOF
+ git diff-files --name-only >actual &&
+ test_cmp expect actual
+'
+
test_expect_success SYMLINKS 'replace a file with a symlink' '
rm foo &&
--
1.8.2.rc2.7.gef06216
^ permalink raw reply related
* Re: [PATCH 1/2] require pathspec for "git add -u/-A"
From: Jeff King @ 2013-03-13 4:08 UTC (permalink / raw)
To: Matthieu Moy; +Cc: Junio C Hamano, git
In-Reply-To: <vpqhakgiusr.fsf@grenoble-inp.fr>
On Tue, Mar 12, 2013 at 02:58:44PM +0100, Matthieu Moy wrote:
> > I guess we already rejected the idea of being able to shut off the
> > warning and just get the new behavior, in favor of having people
> > specify it manually each time?
>
> Somehow, but we may find a way to do so, as long as it temporary (i.e.
> something that will have no effect after the transition period), and
> that is is crystal clear that it's temporary.
Yeah, I think this is easy as long as it is "enable the new behavior
now" and not "toggle between new and old behavior". That is, a boolean
rather than a selector, with a note that it will go away at the behavior
switch.
The only downside I see is that a user may switch it on now, saying
"Yes, I understand and prefer the new behavior", but some script they
run might not expect it. We can warn against that in the documentation,
but that may or may not be enough.
Here's a series which does that; if it's the direction we want to go, I
think we'd want to rebase Junio's "now add -u is full-tree" patch on
top.
[1/2]: t2200: check that "add -u" limits itself to subdirectory
[2/2]: add: respect add.updateroot config option
-Peff
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox