* [PATCH] git-status: show short sequencer state
From: Phil Hord @ 2012-10-23 18:58 UTC (permalink / raw)
To: hordp
Cc: phil.hord, Junio C Hamano, konglu, Matthieu Moy, Kong Lucien, git,
Duperray Valentin, Jonas Franck, Nguy Thomas,
Nguyen Huynh Khoi Nguyen
Recently git-status learned to display the state of the git
sequencer in long form to help the user remember an interrupted
command. This information is also useful in short form to
humans and scripts, but no option is available to boil it down.
Teach git-status to report the sequencer state in short form
using a new --sequencer (-S) switch. Output zero or more
simple state token strings indicating the deduced state of the
git sequencer.
Introduce a common function to determine the current sequencer
state so the regular status function and this short version can
share common code.
Add a substate to wt_status_state to track more detailed
information about a state, such as "conflicted" or "resolved".
Move the am_empty_patch flage out of wt_status_state and into
this new substate.
State token strings which may be emitted and their meanings:
merge a git-merge is in progress
am a git-am is in progress
rebase a git-rebase is in progress
rebase-interactive a git-rebase--interactive is in progress
cherry-pick a git-cherry-pick is in progress
bisect a git-bisect is in progress
conflicted there are unresolved conflicts
resolved conflicts have been resolved
editing interactive rebase stopped to edit a commit
edited interactive rebase edit has been edited
splitting interactive rebase, commit is being split
I also considered adding these tokens, but I decided it was not
appropriate since these changes are not sequencer-related. But
it is possible I am being too short-sighted or have chosen the
switch name poorly.
clean
index
modified
untracked
---
Documentation/git-status.txt | 18 +++++++
builtin/commit.c | 12 ++++-
wt-status.c | 125 +++++++++++++++++++++++++++++++++++--------
wt-status.h | 14 ++++-
4 files changed, 145 insertions(+), 24 deletions(-)
diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt
index 67e5f53..31ffabd 100644
--- a/Documentation/git-status.txt
+++ b/Documentation/git-status.txt
@@ -38,6 +38,24 @@ OPTIONS
across git versions and regardless of user configuration. See
below for details.
+-S::
+--sequence::
+ Show the git sequencer status. This shows zero or more tokens
+ describing the state of several git sequence operations. Each
+ token is separated by a newline.
++
+ merge a merge is in progress
+ am an am is in progress
+ rebase a rebase is in progress
+ rebase-interactive an interactive rebase is in progress
+ cherry-pick a cherry-pick is in progress
+ bisect a bisect is in progress
+ conflicted there are unresolved conflicts
+ resolved conflicts have been resolved
+ editing interactive rebase stopped to edit a commit
+ edited interactive rebase edit has been edited
+ splitting interactive rebase, commit is being split
+
-u[<mode>]::
--untracked-files[=<mode>]::
Show untracked files.
diff --git a/builtin/commit.c b/builtin/commit.c
index a17a5df..9706ed9 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -114,7 +114,8 @@ static struct strbuf message = STRBUF_INIT;
static enum {
STATUS_FORMAT_LONG,
STATUS_FORMAT_SHORT,
- STATUS_FORMAT_PORCELAIN
+ STATUS_FORMAT_PORCELAIN,
+ STATUS_FORMAT_SEQUENCER
} status_format = STATUS_FORMAT_LONG;
static int opt_parse_m(const struct option *opt, const char *arg, int unset)
@@ -454,6 +455,9 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int
case STATUS_FORMAT_PORCELAIN:
wt_porcelain_print(s);
break;
+ case STATUS_FORMAT_SEQUENCER:
+ wt_sequencer_print(s);
+ break;
case STATUS_FORMAT_LONG:
wt_status_print(s);
break;
@@ -1156,6 +1160,9 @@ int cmd_status(int argc, const char **argv, const char *prefix)
N_("show status concisely"), STATUS_FORMAT_SHORT),
OPT_BOOLEAN('b', "branch", &s.show_branch,
N_("show branch information")),
+ OPT_SET_INT('S', "sequence", &status_format,
+ N_("show sequencer state"),
+ STATUS_FORMAT_SEQUENCER),
OPT_SET_INT(0, "porcelain", &status_format,
N_("machine-readable output"),
STATUS_FORMAT_PORCELAIN),
@@ -1216,6 +1223,9 @@ int cmd_status(int argc, const char **argv, const char *prefix)
case STATUS_FORMAT_PORCELAIN:
wt_porcelain_print(&s);
break;
+ case STATUS_FORMAT_SEQUENCER:
+ wt_sequencer_print(&s);
+ break;
case STATUS_FORMAT_LONG:
s.verbose = verbose;
s.ignore_submodule_arg = ignore_submodule_arg;
diff --git a/wt-status.c b/wt-status.c
index 2a9658b..81d91e3 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -781,7 +781,7 @@ static void show_merge_in_progress(struct wt_status *s,
struct wt_status_state *state,
const char *color)
{
- if (has_unmerged(s)) {
+ if (state->substate == WT_SUBSTATE_CONFLICTED) {
status_printf_ln(s, color, _("You have unmerged paths."));
if (advice_status_hints)
status_printf_ln(s, color,
@@ -802,11 +802,11 @@ static void show_am_in_progress(struct wt_status *s,
{
status_printf_ln(s, color,
_("You are in the middle of an am session."));
- if (state->am_empty_patch)
+ if (state->substate == WT_SUBSTATE_AM_EMPTY)
status_printf_ln(s, color,
_("The current patch is empty."));
if (advice_status_hints) {
- if (!state->am_empty_patch)
+ if (state->substate == WT_SUBSTATE_CONFLICTED)
status_printf_ln(s, color,
_(" (fix conflicts and then run \"git am --resolved\")"));
status_printf_ln(s, color,
@@ -867,9 +867,7 @@ static void show_rebase_in_progress(struct wt_status *s,
struct wt_status_state *state,
const char *color)
{
- struct stat st;
-
- if (has_unmerged(s)) {
+ if (state->substate == WT_SUBSTATE_CONFLICTED) {
status_printf_ln(s, color, _("You are currently rebasing."));
if (advice_status_hints) {
status_printf_ln(s, color,
@@ -879,19 +877,19 @@ static void show_rebase_in_progress(struct wt_status *s,
status_printf_ln(s, color,
_(" (use \"git rebase --abort\" to check out the original branch)"));
}
- } else if (state->rebase_in_progress || !stat(git_path("MERGE_MSG"), &st)) {
+ } else if (state->substate == WT_SUBSTATE_RESOLVED) {
status_printf_ln(s, color, _("You are currently rebasing."));
if (advice_status_hints)
status_printf_ln(s, color,
_(" (all conflicts fixed: run \"git rebase --continue\")"));
- } else if (split_commit_in_progress(s)) {
+ } else if (state->substate == WT_SUBSTATE_SPLITTING) {
status_printf_ln(s, color, _("You are currently splitting a commit during a rebase."));
if (advice_status_hints)
status_printf_ln(s, color,
_(" (Once your working directory is clean, run \"git rebase --continue\")"));
} else {
status_printf_ln(s, color, _("You are currently editing a commit during a rebase."));
- if (advice_status_hints && !s->amend) {
+ if (advice_status_hints && state->substate == WT_SUBSTATE_EDITING) {
status_printf_ln(s, color,
_(" (use \"git commit --amend\" to amend the current commit)"));
status_printf_ln(s, color,
@@ -907,7 +905,7 @@ static void show_cherry_pick_in_progress(struct wt_status *s,
{
status_printf_ln(s, color, _("You are currently cherry-picking."));
if (advice_status_hints) {
- if (has_unmerged(s))
+ if (state->substate == WT_SUBSTATE_CONFLICTED)
status_printf_ln(s, color,
_(" (fix conflicts and run \"git commit\")"));
else
@@ -928,34 +926,68 @@ static void show_bisect_in_progress(struct wt_status *s,
wt_status_print_trailer(s);
}
-static void wt_status_print_state(struct wt_status *s)
+static void wt_status_get_state(struct wt_status *s , 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));
+ memset(state, 0, sizeof(*state));
+ // Determine main sequencer activity
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->substate = WT_SUBSTATE_AM_EMPTY;
+ else
+ state->substate = WT_SUBSTATE_CONFLICTED;
} else {
- state.rebase_in_progress = 1;
+ state->rebase_in_progress = 1;
}
} 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->rebase_in_progress = 1;
} 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->bisect_in_progress = 1;
+
+ // Check for unmerged files
+ if (state->rebase_in_progress || state->rebase_interactive_in_progress ||
+ state->cherry_pick_in_progress || state->merge_in_progress) {
+ if (has_unmerged(s)) {
+ state->substate = WT_SUBSTATE_CONFLICTED;
+ } else {
+ state->substate = WT_SUBSTATE_RESOLVED;
+ }
+ }
+
+ // Interactive Rebase is more nuanced
+ if (state->rebase_interactive_in_progress && state->substate != WT_SUBSTATE_CONFLICTED) {
+ if (!stat(git_path("MERGE_MSG"), &st)) {
+ state->substate = WT_SUBSTATE_RESOLVED;
+ } else if (split_commit_in_progress(s)) {
+ state->substate = WT_SUBSTATE_SPLITTING;
+ } else {
+ if (s->amend) {
+ state->substate = WT_SUBSTATE_EDITED;
+ } else {
+ state->substate = WT_SUBSTATE_EDITING;
+ }
+ }
+ }
+}
+
+static void wt_status_print_state(struct wt_status *s)
+{
+ const char *state_color = color(WT_STATUS_HEADER, s);
+ struct wt_status_state state;
+
+ wt_status_get_state(s, &state);
if (state.merge_in_progress)
show_merge_in_progress(s, &state, state_color);
@@ -1192,6 +1224,55 @@ static void wt_shortstatus_print_tracking(struct wt_status *s)
fputc(s->null_termination ? '\0' : '\n', s->fp);
}
+static void wt_print_token(struct wt_status *s, const char *token)
+{
+ fprintf(s->fp, "%s", token);
+ fputc(s->null_termination ? '\0' : '\n', s->fp);
+}
+
+void wt_sequencer_print(struct wt_status *s)
+{
+ struct wt_status_state state;
+
+ wt_status_get_state(s, &state);
+
+ if (state.merge_in_progress)
+ wt_print_token(s, "merge");
+ if (state.am_in_progress)
+ wt_print_token(s, "am");
+ if (state.rebase_in_progress)
+ wt_print_token(s, "rebase");
+ if (state.rebase_interactive_in_progress)
+ wt_print_token(s, "rebase-interactive");
+ if (state.cherry_pick_in_progress)
+ wt_print_token(s, "cherry-pick");
+ if (state.bisect_in_progress)
+ wt_print_token(s, "bisect");
+
+ switch (state.substate) {
+ case WT_SUBSTATE_NOMINAL:
+ break;
+ case WT_SUBSTATE_CONFLICTED:
+ wt_print_token(s, "conflicted");
+ break;
+ case WT_SUBSTATE_RESOLVED:
+ wt_print_token(s, "resolved");
+ break;
+ case WT_SUBSTATE_EDITED:
+ wt_print_token(s, "edited");
+ break;
+ case WT_SUBSTATE_EDITING:
+ wt_print_token(s, "editing");
+ break;
+ case WT_SUBSTATE_SPLITTING:
+ wt_print_token(s, "splitting");
+ break;
+ case WT_SUBSTATE_AM_EMPTY:
+ wt_print_token(s, "am-empty");
+ break;
+ }
+}
+
void wt_shortstatus_print(struct wt_status *s)
{
int i;
diff --git a/wt-status.h b/wt-status.h
index 236b41f..900889c 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -59,6 +59,7 @@ struct wt_status {
unsigned colopts;
int null_termination;
int show_branch;
+ int show_sequencer;
/* These are computed during processing of the individual sections */
int commitable;
@@ -71,14 +72,24 @@ struct wt_status {
struct string_list ignored;
};
+enum wt_status_substate {
+ WT_SUBSTATE_NOMINAL = 0,
+ WT_SUBSTATE_CONFLICTED,
+ WT_SUBSTATE_RESOLVED,
+ WT_SUBSTATE_SPLITTING,
+ WT_SUBSTATE_EDITING,
+ WT_SUBSTATE_EDITED,
+ WT_SUBSTATE_AM_EMPTY,
+};
+
struct wt_status_state {
int merge_in_progress;
int am_in_progress;
- int am_empty_patch;
int rebase_in_progress;
int rebase_interactive_in_progress;
int cherry_pick_in_progress;
int bisect_in_progress;
+ enum wt_status_substate substate;
};
void wt_status_prepare(struct wt_status *s);
@@ -86,6 +97,7 @@ void wt_status_print(struct wt_status *s);
void wt_status_collect(struct wt_status *s);
void wt_shortstatus_print(struct wt_status *s);
+void wt_sequencer_print(struct wt_status *s);
void wt_porcelain_print(struct wt_status *s);
void status_printf_ln(struct wt_status *s, const char *color, const char *fmt, ...)
--
1.8.0.2.gc921d59.dirty
^ permalink raw reply related
* Re: [PATCH] git-submodule add: Record branch name in .gitmodules
From: Nahor @ 2012-10-23 19:16 UTC (permalink / raw)
To: git
In-Reply-To: <61a31f6bc61d4df322a097e32ba472390c583a81.1350923683.git.wking@tremily.us>
On 2012-10-22 09:34, W. Trevor King wrote:
> From: "W. Trevor King" <wking@tremily.us>
>
> This removes a configuration step if you're trying to setup Ævar's
>
> $ git submodule foreach 'git checkout $(git config --file $toplevel/.gitmodules submodule.$name.branch) && git pull'
>
> workflow from
>
> commit f030c96d8643fa0a1a9b2bd9c2f36a77721fb61f
> Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> Date: Fri May 21 16:10:10 2010 +0000
>
> git-submodule foreach: Add $toplevel variable
>
> If you're not using that workflow, I see no harm in recording the
> branch used to determine the original submodule commit.
IMHO, the problem is that this works only for a very specific workflow.
Normal git usage can very easily break this feature.
For instance, the module may later be updated to a commit in branch B
instead of branch A. Unless you remember to also update .gitmodule, you
have then inconsistent information.
A similar issue arises if branch A is deleted from the module later (for
instance because it has been merged in the master branch and is not
useful anymore). Then .gitmodule points to a non-existant branch.
Same thing if a branch is renamed.
Last issue, the branch that exists in your local repository may not
exist in someone else's repository, either because the branch is purely
local, or because it has a different name on the remote repo.
I think a better place to store that kind of information is using
git-notes. That way, if the branch is renamed or deleted, you can easily
update the old notes to use the new name instead.
Nahor
^ permalink raw reply
* [PATCHv2] git-status: show short sequencer state
From: Phil Hord @ 2012-10-23 20:02 UTC (permalink / raw)
To: git
Cc: phil.hord, Junio C Hamano, konglu, Matthieu Moy, Kong Lucien,
Duperray Valentin, Jonas Franck, Nguy Thomas,
Nguyen Huynh Khoi Nguyen
Updated per Matthieu's comments, adding Sign-off and fixing my prefix to have a little "v2" on the end.
Sorry for the extra noise.
Phil
^ permalink raw reply
* [PATCHv2] git-status: show short sequencer state
From: Phil Hord @ 2012-10-23 20:02 UTC (permalink / raw)
To: git
Cc: phil.hord, Junio C Hamano, konglu, Matthieu Moy, Kong Lucien,
Duperray Valentin, Jonas Franck, Nguy Thomas,
Nguyen Huynh Khoi Nguyen, Phil Hord
In-Reply-To: <1351022574-27869-1-git-send-email-hordp@cisco.com>
Recently git-status learned to display the state of the git
sequencer in long form to help the user remember an interrupted
command. This information is also useful in short form to
humans and scripts, but no option is available to boil it down.
Teach git-status to report the sequencer state in short form
using a new --sequencer (-S) switch. Output zero or more
simple state token strings indicating the deduced state of the
git sequencer.
Introduce a common function to determine the current sequencer
state so the regular status function and this short version can
share common code.
Add a substate to wt_status_state to track more detailed
information about a state, such as "conflicted" or "resolved".
Move the am_empty_patch flage out of wt_status_state and into
this new substate.
State token strings which may be emitted and their meanings:
merge a git-merge is in progress
am a git-am is in progress
rebase a git-rebase is in progress
rebase-interactive a git-rebase--interactive is in progress
cherry-pick a git-cherry-pick is in progress
bisect a git-bisect is in progress
conflicted there are unresolved conflicts
resolved conflicts have been resolved
editing interactive rebase stopped to edit a commit
edited interactive rebase edit has been edited
splitting interactive rebase, commit is being split
I also considered adding these tokens, but I decided it was not
appropriate since these changes are not sequencer-related. But
it is possible I am being too short-sighted or have chosen the
switch name poorly.
clean
index
modified
untracked
Signed-off-by: Phil Hord <hordp@cisco.com>
---
Documentation/git-status.txt | 18 +++++++
builtin/commit.c | 12 ++++-
wt-status.c | 125 +++++++++++++++++++++++++++++++++++--------
wt-status.h | 14 ++++-
4 files changed, 145 insertions(+), 24 deletions(-)
diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt
index 67e5f53..31ffabd 100644
--- a/Documentation/git-status.txt
+++ b/Documentation/git-status.txt
@@ -38,6 +38,24 @@ OPTIONS
across git versions and regardless of user configuration. See
below for details.
+-S::
+--sequence::
+ Show the git sequencer status. This shows zero or more tokens
+ describing the state of several git sequence operations. Each
+ token is separated by a newline.
++
+ merge a merge is in progress
+ am an am is in progress
+ rebase a rebase is in progress
+ rebase-interactive an interactive rebase is in progress
+ cherry-pick a cherry-pick is in progress
+ bisect a bisect is in progress
+ conflicted there are unresolved conflicts
+ resolved conflicts have been resolved
+ editing interactive rebase stopped to edit a commit
+ edited interactive rebase edit has been edited
+ splitting interactive rebase, commit is being split
+
-u[<mode>]::
--untracked-files[=<mode>]::
Show untracked files.
diff --git a/builtin/commit.c b/builtin/commit.c
index a17a5df..9706ed9 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -114,7 +114,8 @@ static struct strbuf message = STRBUF_INIT;
static enum {
STATUS_FORMAT_LONG,
STATUS_FORMAT_SHORT,
- STATUS_FORMAT_PORCELAIN
+ STATUS_FORMAT_PORCELAIN,
+ STATUS_FORMAT_SEQUENCER
} status_format = STATUS_FORMAT_LONG;
static int opt_parse_m(const struct option *opt, const char *arg, int unset)
@@ -454,6 +455,9 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int
case STATUS_FORMAT_PORCELAIN:
wt_porcelain_print(s);
break;
+ case STATUS_FORMAT_SEQUENCER:
+ wt_sequencer_print(s);
+ break;
case STATUS_FORMAT_LONG:
wt_status_print(s);
break;
@@ -1156,6 +1160,9 @@ int cmd_status(int argc, const char **argv, const char *prefix)
N_("show status concisely"), STATUS_FORMAT_SHORT),
OPT_BOOLEAN('b', "branch", &s.show_branch,
N_("show branch information")),
+ OPT_SET_INT('S', "sequence", &status_format,
+ N_("show sequencer state"),
+ STATUS_FORMAT_SEQUENCER),
OPT_SET_INT(0, "porcelain", &status_format,
N_("machine-readable output"),
STATUS_FORMAT_PORCELAIN),
@@ -1216,6 +1223,9 @@ int cmd_status(int argc, const char **argv, const char *prefix)
case STATUS_FORMAT_PORCELAIN:
wt_porcelain_print(&s);
break;
+ case STATUS_FORMAT_SEQUENCER:
+ wt_sequencer_print(&s);
+ break;
case STATUS_FORMAT_LONG:
s.verbose = verbose;
s.ignore_submodule_arg = ignore_submodule_arg;
diff --git a/wt-status.c b/wt-status.c
index 2a9658b..81d91e3 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -781,7 +781,7 @@ static void show_merge_in_progress(struct wt_status *s,
struct wt_status_state *state,
const char *color)
{
- if (has_unmerged(s)) {
+ if (state->substate == WT_SUBSTATE_CONFLICTED) {
status_printf_ln(s, color, _("You have unmerged paths."));
if (advice_status_hints)
status_printf_ln(s, color,
@@ -802,11 +802,11 @@ static void show_am_in_progress(struct wt_status *s,
{
status_printf_ln(s, color,
_("You are in the middle of an am session."));
- if (state->am_empty_patch)
+ if (state->substate == WT_SUBSTATE_AM_EMPTY)
status_printf_ln(s, color,
_("The current patch is empty."));
if (advice_status_hints) {
- if (!state->am_empty_patch)
+ if (state->substate == WT_SUBSTATE_CONFLICTED)
status_printf_ln(s, color,
_(" (fix conflicts and then run \"git am --resolved\")"));
status_printf_ln(s, color,
@@ -867,9 +867,7 @@ static void show_rebase_in_progress(struct wt_status *s,
struct wt_status_state *state,
const char *color)
{
- struct stat st;
-
- if (has_unmerged(s)) {
+ if (state->substate == WT_SUBSTATE_CONFLICTED) {
status_printf_ln(s, color, _("You are currently rebasing."));
if (advice_status_hints) {
status_printf_ln(s, color,
@@ -879,19 +877,19 @@ static void show_rebase_in_progress(struct wt_status *s,
status_printf_ln(s, color,
_(" (use \"git rebase --abort\" to check out the original branch)"));
}
- } else if (state->rebase_in_progress || !stat(git_path("MERGE_MSG"), &st)) {
+ } else if (state->substate == WT_SUBSTATE_RESOLVED) {
status_printf_ln(s, color, _("You are currently rebasing."));
if (advice_status_hints)
status_printf_ln(s, color,
_(" (all conflicts fixed: run \"git rebase --continue\")"));
- } else if (split_commit_in_progress(s)) {
+ } else if (state->substate == WT_SUBSTATE_SPLITTING) {
status_printf_ln(s, color, _("You are currently splitting a commit during a rebase."));
if (advice_status_hints)
status_printf_ln(s, color,
_(" (Once your working directory is clean, run \"git rebase --continue\")"));
} else {
status_printf_ln(s, color, _("You are currently editing a commit during a rebase."));
- if (advice_status_hints && !s->amend) {
+ if (advice_status_hints && state->substate == WT_SUBSTATE_EDITING) {
status_printf_ln(s, color,
_(" (use \"git commit --amend\" to amend the current commit)"));
status_printf_ln(s, color,
@@ -907,7 +905,7 @@ static void show_cherry_pick_in_progress(struct wt_status *s,
{
status_printf_ln(s, color, _("You are currently cherry-picking."));
if (advice_status_hints) {
- if (has_unmerged(s))
+ if (state->substate == WT_SUBSTATE_CONFLICTED)
status_printf_ln(s, color,
_(" (fix conflicts and run \"git commit\")"));
else
@@ -928,34 +926,68 @@ static void show_bisect_in_progress(struct wt_status *s,
wt_status_print_trailer(s);
}
-static void wt_status_print_state(struct wt_status *s)
+static void wt_status_get_state(struct wt_status *s , 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));
+ memset(state, 0, sizeof(*state));
+ // Determine main sequencer activity
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->substate = WT_SUBSTATE_AM_EMPTY;
+ else
+ state->substate = WT_SUBSTATE_CONFLICTED;
} else {
- state.rebase_in_progress = 1;
+ state->rebase_in_progress = 1;
}
} 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->rebase_in_progress = 1;
} 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->bisect_in_progress = 1;
+
+ // Check for unmerged files
+ if (state->rebase_in_progress || state->rebase_interactive_in_progress ||
+ state->cherry_pick_in_progress || state->merge_in_progress) {
+ if (has_unmerged(s)) {
+ state->substate = WT_SUBSTATE_CONFLICTED;
+ } else {
+ state->substate = WT_SUBSTATE_RESOLVED;
+ }
+ }
+
+ // Interactive Rebase is more nuanced
+ if (state->rebase_interactive_in_progress && state->substate != WT_SUBSTATE_CONFLICTED) {
+ if (!stat(git_path("MERGE_MSG"), &st)) {
+ state->substate = WT_SUBSTATE_RESOLVED;
+ } else if (split_commit_in_progress(s)) {
+ state->substate = WT_SUBSTATE_SPLITTING;
+ } else {
+ if (s->amend) {
+ state->substate = WT_SUBSTATE_EDITED;
+ } else {
+ state->substate = WT_SUBSTATE_EDITING;
+ }
+ }
+ }
+}
+
+static void wt_status_print_state(struct wt_status *s)
+{
+ const char *state_color = color(WT_STATUS_HEADER, s);
+ struct wt_status_state state;
+
+ wt_status_get_state(s, &state);
if (state.merge_in_progress)
show_merge_in_progress(s, &state, state_color);
@@ -1192,6 +1224,55 @@ static void wt_shortstatus_print_tracking(struct wt_status *s)
fputc(s->null_termination ? '\0' : '\n', s->fp);
}
+static void wt_print_token(struct wt_status *s, const char *token)
+{
+ fprintf(s->fp, "%s", token);
+ fputc(s->null_termination ? '\0' : '\n', s->fp);
+}
+
+void wt_sequencer_print(struct wt_status *s)
+{
+ struct wt_status_state state;
+
+ wt_status_get_state(s, &state);
+
+ if (state.merge_in_progress)
+ wt_print_token(s, "merge");
+ if (state.am_in_progress)
+ wt_print_token(s, "am");
+ if (state.rebase_in_progress)
+ wt_print_token(s, "rebase");
+ if (state.rebase_interactive_in_progress)
+ wt_print_token(s, "rebase-interactive");
+ if (state.cherry_pick_in_progress)
+ wt_print_token(s, "cherry-pick");
+ if (state.bisect_in_progress)
+ wt_print_token(s, "bisect");
+
+ switch (state.substate) {
+ case WT_SUBSTATE_NOMINAL:
+ break;
+ case WT_SUBSTATE_CONFLICTED:
+ wt_print_token(s, "conflicted");
+ break;
+ case WT_SUBSTATE_RESOLVED:
+ wt_print_token(s, "resolved");
+ break;
+ case WT_SUBSTATE_EDITED:
+ wt_print_token(s, "edited");
+ break;
+ case WT_SUBSTATE_EDITING:
+ wt_print_token(s, "editing");
+ break;
+ case WT_SUBSTATE_SPLITTING:
+ wt_print_token(s, "splitting");
+ break;
+ case WT_SUBSTATE_AM_EMPTY:
+ wt_print_token(s, "am-empty");
+ break;
+ }
+}
+
void wt_shortstatus_print(struct wt_status *s)
{
int i;
diff --git a/wt-status.h b/wt-status.h
index 236b41f..900889c 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -59,6 +59,7 @@ struct wt_status {
unsigned colopts;
int null_termination;
int show_branch;
+ int show_sequencer;
/* These are computed during processing of the individual sections */
int commitable;
@@ -71,14 +72,24 @@ struct wt_status {
struct string_list ignored;
};
+enum wt_status_substate {
+ WT_SUBSTATE_NOMINAL = 0,
+ WT_SUBSTATE_CONFLICTED,
+ WT_SUBSTATE_RESOLVED,
+ WT_SUBSTATE_SPLITTING,
+ WT_SUBSTATE_EDITING,
+ WT_SUBSTATE_EDITED,
+ WT_SUBSTATE_AM_EMPTY,
+};
+
struct wt_status_state {
int merge_in_progress;
int am_in_progress;
- int am_empty_patch;
int rebase_in_progress;
int rebase_interactive_in_progress;
int cherry_pick_in_progress;
int bisect_in_progress;
+ enum wt_status_substate substate;
};
void wt_status_prepare(struct wt_status *s);
@@ -86,6 +97,7 @@ void wt_status_print(struct wt_status *s);
void wt_status_collect(struct wt_status *s);
void wt_shortstatus_print(struct wt_status *s);
+void wt_sequencer_print(struct wt_status *s);
void wt_porcelain_print(struct wt_status *s);
void status_printf_ln(struct wt_status *s, const char *color, const char *fmt, ...)
--
1.8.0.2.gc921d59.dirty
^ permalink raw reply related
* Re: [PATCH] git-submodule add: Record branch name in .gitmodules
From: Jens Lehmann @ 2012-10-23 20:36 UTC (permalink / raw)
To: Nahor; +Cc: git, wking
In-Reply-To: <5086ED06.5020406@gmail.com>
Am 23.10.2012 21:16, schrieb Nahor:
> On 2012-10-22 09:34, W. Trevor King wrote:
>> From: "W. Trevor King" <wking@tremily.us>
>>
>> This removes a configuration step if you're trying to setup Ævar's
>>
>> $ git submodule foreach 'git checkout $(git config --file $toplevel/.gitmodules submodule.$name.branch) && git pull'
>>
>> workflow from
>>
>> commit f030c96d8643fa0a1a9b2bd9c2f36a77721fb61f
>> Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
>> Date: Fri May 21 16:10:10 2010 +0000
>>
>> git-submodule foreach: Add $toplevel variable
>>
>> If you're not using that workflow, I see no harm in recording the
>> branch used to determine the original submodule commit.
Except recording the branch name might raise expectations about what git
will do with it. And as far as this patch goes, git won't do anything
with it (yet).
> IMHO, the problem is that this works only for a very specific workflow. Normal git usage can very easily break this feature.
>
> For instance, the module may later be updated to a commit in branch B instead of branch A. Unless you remember to also update .gitmodule, you have then inconsistent information.
>
> A similar issue arises if branch A is deleted from the module later (for instance because it has been merged in the master branch and is not useful anymore). Then .gitmodule points to a non-existant branch.
> Same thing if a branch is renamed.
Those are valid points. The next "git submodule update" will leave the
submodule with a detached HEAD, making the branch configuration rather
meaningless (except for your "git submodule foreach ..." use case of
course).
> Last issue, the branch that exists in your local repository may not exist in someone else's repository, either because the branch is purely local, or because it has a different name on the remote repo.
You'll always face this kind of problems with commits too when using
submodules, so I don't see that as a problem here.
> I think a better place to store that kind of information is using git-notes. That way, if the branch is renamed or deleted, you can easily update the old notes to use the new name instead.
I can't comment on that, as I have never been using notes so far.
But I'd rather see a patch series properly implementing the always-tip
mode Ævar mentions in f030c96d86 (and which is requested by some users),
especially the interesting parts: What should git record as commit in
that case and how are "git status" and "git diff" going to handle
submodules which shall follow a specific branch. I assume "git submodule
update" is the right point in time to fetch that branch again and check
out a newer branch tip if necessary, but should that commit be added to
the superproject for that submodule automagically or not? This patch
falls short of this, as it does the easy part but not the interesting
ones ;-)
^ permalink raw reply
* [PATCHv2] git-pull: Avoid merge-base on detached head
From: Phil Hord @ 2012-10-23 20:39 UTC (permalink / raw)
To: git; +Cc: phil.hord, Junio C Hamano, Phil Hord
In-Reply-To: <1351024796-28174-1-git-send-email-hordp@cisco.com>
git pull --rebase does some clever tricks to find the base
for $upstream , but it forgets that we may not have any
branch at all. When this happens, git merge-base reports its
"usage" help in the middle of an otherwise successful
rebase operation, because git-merge is called with one too
few parameters.
Since we do not need the merge-base trick in the case of a
detached HEAD, detect this condition and bypass the clever
trick and the usage noise.
Signed-off-by: Phil Hord <hordp@cisco.com>
---
git-pull.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/git-pull.sh b/git-pull.sh
index 2a10047..266e682 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -200,6 +200,7 @@ test true = "$rebase" && {
require_clean_work_tree "pull with rebase" "Please commit or stash them."
fi
oldremoteref= &&
+ test -n "$curr_branch" &&
. git-parse-remote &&
remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
oldremoteref="$(git rev-parse -q --verify "$remoteref")" &&
--
1.8.0.2.gc921d59.dirty
^ permalink raw reply related
* [PATCHv2] git-pull: Avoid merge-base on detached head
From: Phil Hord @ 2012-10-23 20:39 UTC (permalink / raw)
To: git; +Cc: phil.hord, Junio C Hamano
Add Signed-off-by...
^ permalink raw reply
* Re: [PATCH] git-submodule add: Record branch name in .gitmodules
From: W. Trevor King @ 2012-10-23 19:44 UTC (permalink / raw)
To: Nahor; +Cc: git
In-Reply-To: <5086ED06.5020406@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1635 bytes --]
On Tue, Oct 23, 2012 at 12:16:22PM -0700, Nahor wrote:
> On 2012-10-22 09:34, W. Trevor King wrote:
> For instance, the module may later be updated to a commit in branch B
> instead of branch A. Unless you remember to also update .gitmodule, you
> have then inconsistent information.
But you're explicitly *using* the configured setting in
git config --file $toplevel/.gitmodules submodule.$name.branch
That should be a reminder that the configuration is important, and
you'll remember to change it. Plus, the text from git-pull should
clearly display the branch you are pulling, which gives you a second
change to notice if something is going wrong.
> A similar issue arises if branch A is deleted from the module later (for
> instance because it has been merged in the master branch and is not
> useful anymore). Then .gitmodule points to a non-existant branch.
> Same thing if a branch is renamed.
All of these are possible, and all would reqire manual intervention to
pick out a new branch to follow. Plus, this patch is not even about
the auto-pull application, it's about storing the initially cloned
branch name. What you do with that name afterwards is up to you ;).
> I think a better place to store that kind of information is using
> git-notes. That way, if the branch is renamed or deleted, you can easily
> update the old notes to use the new name instead.
Interesting. What would you attach the note too?
Trevor
--
This email may be signed or encrypted with GnuPG (http://www.gnupg.org).
For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH] tile: support GENERIC_KERNEL_THREAD and GENERIC_KERNEL_EXECVE
From: Thomas Gleixner @ 2012-10-23 20:47 UTC (permalink / raw)
To: Al Viro
Cc: Chris Metcalf, LKML, linux-arch, Linus Torvalds, Catalin Marinas,
git, Junio C Hamano
In-Reply-To: <20121023184122.GZ2616@ZenIV.linux.org.uk>
On Tue, 23 Oct 2012, Al Viro wrote:
> On Tue, Oct 23, 2012 at 01:30:26PM -0400, Chris Metcalf wrote:
>
> > I fetched the series from your arch-tile branch and built it, and it works
> > fine. It looks good from my inspection:
> >
> > Acked-by: Chris Metcalf <cmetcalf@tilera.com>
>
> Thanks; Acked-by applied, branch pushed and put into no-rebase mode.
>
> BTW, something like detached Acked-by objects might be a good idea - i.e.
> commit-like git object with amendment to commit message of a given ancestor.
> The situation when ACKs come only after the commit has been pushed is quite
> common. Linus, what do you think about usefulness of such thing? Ability
> to append ACKed-by/Tested-by of an earlier commit to a branch instead of
> git commit --amend + possibly some cherry-picks + force-push, that is.
I agree that this is a common issue. Acked-by/Reviewed-by mails come
in after the fact that the patch has been committed to an immutable
(i.e no-rebase mode) branch or if the change in question already hit
Linus tree.
Still it would be nice to have a recording of that in the git tree
itself.
Something like: "git --attach SHA1 <comment>" would be appreciated!
Thanks,
tglx
^ permalink raw reply
* Re: [PATCH] tile: support GENERIC_KERNEL_THREAD and GENERIC_KERNEL_EXECVE
From: Jeff King @ 2012-10-23 20:51 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Al Viro, Chris Metcalf, LKML, linux-arch, Linus Torvalds,
Catalin Marinas, git, Junio C Hamano
In-Reply-To: <alpine.LFD.2.02.1210232232070.2756@ionos>
On Tue, Oct 23, 2012 at 10:47:28PM +0200, Thomas Gleixner wrote:
> I agree that this is a common issue. Acked-by/Reviewed-by mails come
> in after the fact that the patch has been committed to an immutable
> (i.e no-rebase mode) branch or if the change in question already hit
> Linus tree.
>
> Still it would be nice to have a recording of that in the git tree
> itself.
>
> Something like: "git --attach SHA1 <comment>" would be appreciated!
It is spelled:
git notes add -m <comment> SHA1
The resulting notes are stored in a separate revision-controlled branch
and can be pushed and pulled like regular refs. Note, though, that the
default refspecs do not yet include refs/notes, so you'd have to add
them manually. The workflows around notes are not very mature yet, so if
you start using them, feedback would be appreciated.
-Peff
^ permalink raw reply
* Re: Git submodule for a local branch?
From: Jens Lehmann @ 2012-10-23 20:57 UTC (permalink / raw)
To: W. Trevor King; +Cc: Git
In-Reply-To: <20121022123714.GL25563@odin.tremily.us>
Am 22.10.2012 14:37, schrieb W. Trevor King:
> I have a bunch of branches in my repo (a, b, c, …), and I'd like to
> check them out into subdirectories of another branch (index). My
> initial inclination was to use something like
>
> $ git checkout index
> $ git branch
> a
> b
> c
> * index
> $ git submodule add -b a --reference ./ ./ dir-for-a/
> $ git submodule add -b b --reference ./ ./ dir-for-b/
> $ git submodule add -b c --reference ./ ./ dir-for-c/
>
> but cloning a remote repository (vs. checking out a local branch)
> seems to be baked into the submodule implementation. Should I be
> thinking about generalizing git-submodule.sh, or am I looking under
> the wrong rock? My ideal syntax would be something like
>
> $ git submodule add -b c --local dir-for-c/
But then we'd have to be able to have two (or more) work trees using
the same git directory, which current submodule code can't.
> The motivation is that I have website that contains a bunch of
> sub-sites, and the sub-sites share content. I have per-sub-site
> branches (a, b, c) and want a master branch (index) that aggregates
> them. Perhaps this is too much to wedge into a single repository?
To me this sounds upside-down. I'd put the three sub-sites into
different repositories and the shared content into a submodule that
all three sub-sites use. At least that is how I do all my content
sharing on the websites I have done ... does that make sense?
^ permalink raw reply
* [PATCH] git-submodule: wrap branch option with "<>" in usage strings.
From: W. Trevor King @ 2012-10-23 21:00 UTC (permalink / raw)
To: Git; +Cc: W. Trevor King
From: "W. Trevor King" <wking@tremily.us>
Use "-b <branch>" instead of "-b branch". This brings the usage
strings in line with other options, e.g. "--reference <repository>".
Signed-off-by: W. Trevor King <wking@tremily.us>
---
Documentation/git-submodule.txt | 2 +-
git-submodule.sh | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index b4683bb..a65f38e 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -9,7 +9,7 @@ git-submodule - Initialize, update or inspect submodules
SYNOPSIS
--------
[verse]
-'git submodule' [--quiet] add [-b branch] [-f|--force]
+'git submodule' [--quiet] add [-b <branch>] [-f|--force]
[--reference <repository>] [--] <repository> [<path>]
'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]
'git submodule' [--quiet] init [--] [<path>...]
diff --git a/git-submodule.sh b/git-submodule.sh
index ab6b110..02f82e9 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -5,7 +5,7 @@
# Copyright (c) 2007 Lars Hjemli
dashless=$(basename "$0" | sed -e 's/-/ /')
-USAGE="[--quiet] add [-b branch] [-f|--force] [--reference <repository>] [--] <repository> [<path>]
+USAGE="[--quiet] add [-b <branch>] [-f|--force] [--reference <repository>] [--] <repository> [<path>]
or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
or: $dashless [--quiet] init [--] [<path>...]
or: $dashless [--quiet] update [--init] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
--
1.8.0.2.g09b91ca
^ permalink raw reply related
* Re: [PATCH] tile: support GENERIC_KERNEL_THREAD and GENERIC_KERNEL_EXECVE
From: Catalin Marinas @ 2012-10-23 21:09 UTC (permalink / raw)
To: Jeff King
Cc: Thomas Gleixner, Al Viro, Chris Metcalf, LKML, linux-arch,
Linus Torvalds, git, Junio C Hamano
In-Reply-To: <20121023205119.GA27729@sigill.intra.peff.net>
On 23 October 2012 21:51, Jeff King <peff@peff.net> wrote:
> On Tue, Oct 23, 2012 at 10:47:28PM +0200, Thomas Gleixner wrote:
>
>> I agree that this is a common issue. Acked-by/Reviewed-by mails come
>> in after the fact that the patch has been committed to an immutable
>> (i.e no-rebase mode) branch or if the change in question already hit
>> Linus tree.
>>
>> Still it would be nice to have a recording of that in the git tree
>> itself.
>>
>> Something like: "git --attach SHA1 <comment>" would be appreciated!
>
> It is spelled:
>
> git notes add -m <comment> SHA1
>
> The resulting notes are stored in a separate revision-controlled branch
> and can be pushed and pulled like regular refs. Note, though, that the
> default refspecs do not yet include refs/notes, so you'd have to add
> them manually. The workflows around notes are not very mature yet, so if
> you start using them, feedback would be appreciated.
What would be nice is that notes are pushed/pulled automatically with
standard git push/fetch/pull commands. Usually git walks the DAG
starting with the pulled commit or tag and following the parents. With
notes, the reference is reversed, the note pointing to the commit and
not the other way around. So handling this automatically in Git would
be really useful.
The other feature I'd like is that notes are automatically folded in
the log during git rebase (maybe similar to the squash option). If you
rebase, you lose all the notes (though this depends on the workflow,
it may not be needed with published branches).
--
Catalin
^ permalink raw reply
* Re: [PATCH] tile: support GENERIC_KERNEL_THREAD and GENERIC_KERNEL_EXECVE
From: Jeff King @ 2012-10-23 21:22 UTC (permalink / raw)
To: Catalin Marinas
Cc: Thomas Gleixner, Al Viro, Chris Metcalf, LKML, linux-arch,
Linus Torvalds, git, Junio C Hamano
In-Reply-To: <CAHkRjk6x9ToVzY7jv1ZxPt57F6agcH7SfHZpZNpHC3QP3PZp3Q@mail.gmail.com>
On Tue, Oct 23, 2012 at 10:09:46PM +0100, Catalin Marinas wrote:
> > It is spelled:
> >
> > git notes add -m <comment> SHA1
> >
> > The resulting notes are stored in a separate revision-controlled branch
> > and can be pushed and pulled like regular refs. Note, though, that the
> > default refspecs do not yet include refs/notes, so you'd have to add
> > them manually. The workflows around notes are not very mature yet, so if
> > you start using them, feedback would be appreciated.
>
> What would be nice is that notes are pushed/pulled automatically with
> standard git push/fetch/pull commands. Usually git walks the DAG
> starting with the pulled commit or tag and following the parents. With
> notes, the reference is reversed, the note pointing to the commit and
> not the other way around. So handling this automatically in Git would
> be really useful.
Right, that's what I meant about the refspecs. You can configure git to
push or pull them automatically, but it is not the default. Something
like:
git config --add remote.origin.fetch '+refs/notes/*:refs/notes/origin/*'
would be a start, but you'd also want to "git notes merge" upstream's
changes into your local notes (you _could_ just fetch straight into
refs/notes/, but if you are making your own notes locally, you have to
resolve it somehow). Exactly how to make this smooth is one of the workflow
considerations; there's been discussion, but most people aren't using
the feature, so we don't have a lot of data.
If you are asking whether we could "auto-follow" notes for commits that
have been fetched like we do for tags, the answer is "not really". The
notes tree is version-controlled as a whole, so you generally fetch the
whole thing or not. And the remote does not advertise note information
the same way we advertise peeled tag references, so a client does not
know which notes are available for fetch. The intended strategy is to
pull in the notes or not (though you can have multiple notes refs with
different names, and fetch just a subset of them).
> The other feature I'd like is that notes are automatically folded in
> the log during git rebase (maybe similar to the squash option). If you
> rebase, you lose all the notes (though this depends on the workflow,
> it may not be needed with published branches).
Git-rebase can automatically copy notes from one commit to another
during a rebase, but you need to set notes.rewriteRef to do so (see "git
help config" for details). The reason for this conservative default is
that some notes may not be appropriate for automatic copying (e.g., a
notes tree containing QA approval should probably be invalidated during
a rebase, whereas one with commentary probably should).
Squashing the notes into the commit message during rebase would be a
useful feature (at least for some type of notes), but that feature does
not currently exist (and as far as I recall, this is the first it has
been proposed).
Again, I think a lot of this comes down to the fact that not many people
are really using notes for their daily workflow, so these itches are not
coming up and getting scratched.
-Peff
^ permalink raw reply
* Re: [PATCH] tile: support GENERIC_KERNEL_THREAD and GENERIC_KERNEL_EXECVE
From: Thomas Gleixner @ 2012-10-23 21:25 UTC (permalink / raw)
To: Jeff King
Cc: Al Viro, Chris Metcalf, LKML, linux-arch, Linus Torvalds,
Catalin Marinas, git, Junio C Hamano
In-Reply-To: <20121023205119.GA27729@sigill.intra.peff.net>
On Tue, 23 Oct 2012, Jeff King wrote:
> On Tue, Oct 23, 2012 at 10:47:28PM +0200, Thomas Gleixner wrote:
>
> > I agree that this is a common issue. Acked-by/Reviewed-by mails come
> > in after the fact that the patch has been committed to an immutable
> > (i.e no-rebase mode) branch or if the change in question already hit
> > Linus tree.
> >
> > Still it would be nice to have a recording of that in the git tree
> > itself.
> >
> > Something like: "git --attach SHA1 <comment>" would be appreciated!
>
> It is spelled:
>
> git notes add -m <comment> SHA1
Cool!
> The resulting notes are stored in a separate revision-controlled branch
Which branch(es) is/are that ? What are the semantics of that?
Assume I commit something to branch "foo"
Now I get that late Ack/Reviewed-by and want to associate that to that
commit in branch "foo". Does that go into "notes/foo" ?
If yes, good. (Any other sensible prefix is good as well). If no,
where does it go to?
Later when I send a pull request to my upstream maintainer for branch
"foo" does he get "notes/foo" automagically or do I have to request to
pull him that separately?
Either way is fine for me, though something which lets me "automate"
that would be appreciated. I can work around that easily as my pull
requests are generated via scripts, so I can add the secondary one for
the dependent "notes" branch if necessary. Though it would be nice to
avoid that. Avoiding that, i.e having a straight connection (maybe
configurable) between "foo" and "notes/foo" and the commits which have
not yet hit my upstream maintainer would make my life easier. I.e. I
just have to check "foo" for stuff which is not upstream yet instead
of checking both, but that might just be my laziness.
Thoughts?
tglx
^ permalink raw reply
* Re: [PATCH] git-submodule add: Record branch name in .gitmodules
From: W. Trevor King @ 2012-10-23 20:44 UTC (permalink / raw)
To: Nahor, Phil Hord; +Cc: git
In-Reply-To: <20121023194436.GD28592@odin.tremily.us>
[-- Attachment #1: Type: text/plain, Size: 2028 bytes --]
On Tue, Oct 23, 2012 at 03:44:36PM -0400, W. Trevor King wrote:
> On Tue, Oct 23, 2012 at 12:16:22PM -0700, Nahor wrote:
> > On 2012-10-22 09:34, W. Trevor King wrote:
> > For instance, the module may later be updated to a commit in branch B
> > instead of branch A. Unless you remember to also update .gitmodule, you
> > have then inconsistent information.
>
> But you're explicitly *using* the configured setting in
>
> git config --file $toplevel/.gitmodules submodule.$name.branch
>
> That should be a reminder that the configuration is important, and
> you'll remember to change it.
To make my case more cleanly, people already handle all the
troublesome cases for branch.$name.remote, so handling similar
upstream volatility for submodule.$name.branch should not be too
difficult or surprising.
On Tue, Oct 23, 2012 at 03:58:48PM -0400, Phil Hord wrote:
> On Mon, Oct 22, 2012 at 6:55 PM, W. Trevor King <wking@tremily.us> wrote:
> > How about -r/--record, with the recorded name being optional?
> >
> > --record-branch[=<recorded_name>]
>
> I like that just fine.
>
> > This would satisfy Gerrit users that wanted to use '.', but also
> > satisfy me with:
> >
> > git submodule add -rb=master foo bar
> >
> > However, there is a change that people would see that, and then use
> >
> > git submodule add -r -b=master foo bar
> >
> > which would checkout the HEAD from foo and store `-b=master` in
> > submodule.$name.branch.
>
> I don't think it would.
Ah, right, forcing the =<name> attached case would mean they'd have to
use
git submodule add -r=-b=master
which doesn't sound like the sort of thing you'd do accidentally.
> Though I see in rev-parse--parseopts that the use of
> optional-argument options "is discouraged".
I'll work up a v2 patch and we'll see if anyone complains ;).
--
This email may be signed or encrypted with GnuPG (http://www.gnupg.org).
For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH] git-submodule add: Record branch name in .gitmodules
From: Nahor @ 2012-10-23 21:45 UTC (permalink / raw)
To: git
In-Reply-To: <20121023194436.GD28592@odin.tremily.us>
On 2012-10-23 12:44, W. Trevor King wrote:
> On Tue, Oct 23, 2012 at 12:16:22PM -0700, Nahor wrote:
>> On 2012-10-22 09:34, W. Trevor King wrote:
>> For instance, the module may later be updated to a commit in branch B
>> instead of branch A. Unless you remember to also update .gitmodule, you
>> have then inconsistent information.
>
> But you're explicitly *using* the configured setting in
>
> git config --file $toplevel/.gitmodules submodule.$name.branch
>
> That should be a reminder that the configuration is important, and
> you'll remember to change it.
From my experience with my colleagues at work, that's not going to
happen. People are very good at forgetting to do something ;)
> Plus, the text from git-pull should
> clearly display the branch you are pulling, which gives you a second
> change to notice if something is going wrong.
That's assuming that the user knows the branch that should be pulled and
that he's paying attention to the output and not just quick-scanning for
errors/warnings.
Again, from my experience, that's not going to be the case.
Plus, there isn't always a human being behind a git-pull, e.g. build bots.
>> I think a better place to store that kind of information is using
>> git-notes. That way, if the branch is renamed or deleted, you can easily
>> update the old notes to use the new name instead.
>
> Interesting. What would you attach the note too?
To the commits in the super-repo where a module branch is selected, i.e.:
- where a module was added
- where the module changed branch
- where a super-branch was merged and there was a conflict on the
module's branch name
^ permalink raw reply
* Re: [PATCH] tile: support GENERIC_KERNEL_THREAD and GENERIC_KERNEL_EXECVE
From: Jeff King @ 2012-10-23 21:47 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Al Viro, Chris Metcalf, LKML, linux-arch, Linus Torvalds,
Catalin Marinas, git, Junio C Hamano
In-Reply-To: <alpine.LFD.2.02.1210232307480.2756@ionos>
On Tue, Oct 23, 2012 at 11:25:06PM +0200, Thomas Gleixner wrote:
> > The resulting notes are stored in a separate revision-controlled branch
>
> Which branch(es) is/are that ? What are the semantics of that?
They are stored in refs/notes/commits by default, but you can have
multiple notes refs if you want to store logically distinct sets of
notes.
A notes ref's tree is just a tree whose entries are sha1s, and the file
contents contain the notes themselves (the sha1s are broken down into
subdirectories for performance, but "git notes" handles this behind the
scenes). Technically you could check it out as a branch, edit, and
commit, but "git checkout" is not happy to have a HEAD outside of
refs/heads/, so you are stuck with plumbing like:
$ git checkout `git rev-parse refs/notes/commits`
$ edit edit edit
$ git commit ...
$ git update-ref refs/notes/commits HEAD
It's probably not good for much beyond exploring how notes are
implemented. See "git help notes" for more discussion.
> Assume I commit something to branch "foo"
>
> Now I get that late Ack/Reviewed-by and want to associate that to that
> commit in branch "foo". Does that go into "notes/foo" ?
No. It would go into refs/notes/commits, or you could ask it to go to
refs/notes/acks if you wanted to keep them separate from your default
notes. It is indexed by commit object, not by branch (so if that branch
later goes away, the notes are always still attached to the commit
objects, assuming they got merged in).
> Later when I send a pull request to my upstream maintainer for branch
> "foo" does he get "notes/foo" automagically or do I have to request to
> pull him that separately?
No, he would have to pull your notes separately. Most of the discussion
around sharing has been configuring the default refspec configuration to
fetch notes. But in the kernel you guys use a lot of one-off pulls
without configured remotes. I'm not sure what the right workflow would
be. It might simply be to ask git to always pull particular notes
commits at the same time (so you might push your notes to
refs/notes/for-linus, and then git would automatically grab the notes
when somebody pulls refs/heads/for-linus).
> Either way is fine for me, though something which lets me "automate"
> that would be appreciated. I can work around that easily as my pull
> requests are generated via scripts, so I can add the secondary one for
> the dependent "notes" branch if necessary. Though it would be nice to
> avoid that. Avoiding that, i.e having a straight connection (maybe
> configurable) between "foo" and "notes/foo" and the commits which have
> not yet hit my upstream maintainer would make my life easier. I.e. I
> just have to check "foo" for stuff which is not upstream yet instead
> of checking both, but that might just be my laziness.
>
> Thoughts?
That all makes sense. Putting extra work on the puller is not a good
long-term solution. So while sending them an extra "also pull these
notes" line, even if it ends up being a cut-and-pastable single-liner,
is not great (even if it is the most flexible thing). Using a convention
based on name-equivalence seems like a sensible compromise.
-Peff
^ permalink raw reply
* Re: [PATCH] git-submodule add: Record branch name in .gitmodules
From: W. Trevor King @ 2012-10-23 20:55 UTC (permalink / raw)
To: Jens Lehmann; +Cc: Phil Hord, Nahor, git
In-Reply-To: <5086FFDC.2050700@web.de>
[-- Attachment #1: Type: text/plain, Size: 2219 bytes --]
On Tue, Oct 23, 2012 at 10:36:44PM +0200, Jens Lehmann wrote:
> Except recording the branch name might raise expectations about what git
> will do with it. And as far as this patch goes, git won't do anything
> with it (yet).
As Phil pointed out, doing anything with this variable is ambiguous:
On Mon, Oct 22, 2012 at 06:03:53PM -0400, Phil Hord wrote:
> Some projects now use the 'branch' config value to record the tracking
> branch for the submodule. Some ascribe different meaning to the
> configuration if the value is given vs. undefined. For example, see
> the Gerrit submodule-subscription mechanism. This change will cause
> those workflows to behave differently than they do now.
On Tue, Oct 23, 2012 at 10:36:44PM +0200, Jens Lehmann wrote:
> But I'd rather see a patch series properly implementing the always-tip
> mode Ævar mentions in f030c96d86 (and which is requested by some users),
> especially the interesting parts: What should git record as commit in
> that case and how are "git status" and "git diff" going to handle
> submodules which shall follow a specific branch. I assume "git submodule
> update" is the right point in time to fetch that branch again and check
> out a newer branch tip if necessary, but should that commit be added to
> the superproject for that submodule automagically or not? This patch
> falls short of this, as it does the easy part but not the interesting
> ones ;-)
I agree that I'm not working on always-tip. I'm just making that
easier. For people that aren't interested in always-tip submodules
(e.g. Gerrit folks), this patch is still useful. It would certainly
be possible to build an always-tip implementation on top of
submodule.$name.branch (as Ævar's one-liner does), but that would be
another patch series.
Personally, I think truly updates should be made explicitly, with a
hand written commit message about why the updates are occuring. I
also think that setting up and running auto-updates should be easy
one-liners, not long, complicated ones ;).
--
This email may be signed or encrypted with GnuPG (http://www.gnupg.org).
For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* [PATCH v2] git-submodule add: Add -r/--record option.
From: W. Trevor King @ 2012-10-23 21:57 UTC (permalink / raw)
To: Git; +Cc: Nahor, Phil Hord, W. Trevor King
In-Reply-To: <20121023204437.GE28592@odin.tremily.us>
From: "W. Trevor King" <wking@tremily.us>
This option allows you to record a submodule.<name>.branch option in
.gitmodules. Git does not currently use this configuration option for
anything, but users have used it for several things, so it makes sense
to add some syntactic sugar for initializing the value.
Current consumers:
Ævar uses this setting to designate the upstream branch for pulling
submodule updates:
$ git submodule foreach 'git checkout $(git config --file $toplevel/.gitmodules submodule.$name.branch) && git pull'
as he describes in
commit f030c96d8643fa0a1a9b2bd9c2f36a77721fb61f
Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Date: Fri May 21 16:10:10 2010 +0000
git-submodule foreach: Add $toplevel variable
Gerrit uses this setting to
“indicate the branch of a submodule project that when updated will
trigger automatic update of its registered gitlink.” [1]
I'm not clear on what that means, but they accept special values like
'.', so their usage is not compatible with Ævar's proposal.
By remaining agnostic on the variable usage, this patch makes
submodule setup more convenient for all parties.
[1] https://gerrit.googlesource.com/gerrit/+/master/Documentation/user-submodules.txt
Signed-off-by: W. Trevor King <wking@tremily.us>
---
Documentation/git-submodule.txt | 11 ++++++++++-
git-submodule.sh | 19 ++++++++++++++++++-
t/t7400-submodule-basic.sh | 25 +++++++++++++++++++++++++
3 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index b4683bb..f9c74d6 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -9,7 +9,7 @@ git-submodule - Initialize, update or inspect submodules
SYNOPSIS
--------
[verse]
-'git submodule' [--quiet] add [-b branch] [-f|--force]
+'git submodule' [--quiet] add [-b branch] [--record[=<branch>]] [-f|--force]
[--reference <repository>] [--] <repository> [<path>]
'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]
'git submodule' [--quiet] init [--] [<path>...]
@@ -209,6 +209,15 @@ OPTIONS
--branch::
Branch of repository to add as submodule.
+-r::
+--record::
+ Record a branch name used as `submodule.<path>.branch` in
+ `.gitmodules` for future reference. If you do not list an explicit
+ name here, the name given with `--branch` will be recorded. If that
+ is not set either, `HEAD` will be recorded. Because the branch name
+ is optional, you must use the equal-sign form (`-r=<branch>`), not
+ `-r <branch>`.
+
-f::
--force::
This option is only valid for add and update commands.
diff --git a/git-submodule.sh b/git-submodule.sh
index ab6b110..bc33112 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -5,7 +5,7 @@
# Copyright (c) 2007 Lars Hjemli
dashless=$(basename "$0" | sed -e 's/-/ /')
-USAGE="[--quiet] add [-b branch] [-f|--force] [--reference <repository>] [--] <repository> [<path>]
+USAGE="[--quiet] add [-b branch] [--record[=<branch>]] [-f|--force] [--reference <repository>] [--] <repository> [<path>]
or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
or: $dashless [--quiet] init [--] [<path>...]
or: $dashless [--quiet] update [--init] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
@@ -20,6 +20,8 @@ require_work_tree
command=
branch=
+record_branch=
+record_branch_empty=
force=
reference=
cached=
@@ -257,6 +259,12 @@ cmd_add()
branch=$2
shift
;;
+ -r | --record)
+ record_branch_empty=true
+ ;;
+ -r=* | --record=*)
+ record_branch="${1#*=}"
+ ;;
-f | --force)
force=$1
;;
@@ -328,6 +336,11 @@ cmd_add()
git ls-files --error-unmatch "$sm_path" > /dev/null 2>&1 &&
die "$(eval_gettext "'\$sm_path' already exists in the index")"
+ if test -z "$record_branch" && test "$record_branch_empty" = "true"
+ then
+ record_branch="${branch:=HEAD}"
+ fi
+
if test -z "$force" && ! git add --dry-run --ignore-missing "$sm_path" > /dev/null 2>&1
then
eval_gettextln "The following path is ignored by one of your .gitignore files:
@@ -366,6 +379,10 @@ Use -f if you really want to add it." >&2
git config -f .gitmodules submodule."$sm_path".path "$sm_path" &&
git config -f .gitmodules submodule."$sm_path".url "$repo" &&
+ if test -n "$branch"
+ then
+ git config -f .gitmodules submodule."$sm_path".branch "$record_branch"
+ fi &&
git add --force .gitmodules ||
die "$(eval_gettext "Failed to register submodule '\$sm_path'")"
}
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 5397037..88ae74c 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -133,6 +133,7 @@ test_expect_success 'submodule add --branch' '
(
cd addtest &&
git submodule add -b initial "$submodurl" submod-branch &&
+ test -z "$(git config -f .gitmodules submodule.submod-branch.branch)" &&
git submodule init
) &&
@@ -211,6 +212,30 @@ test_expect_success 'submodule add with ./, /.. and // in path' '
test_cmp empty untracked
'
+test_expect_success 'submodule add --record' '
+ (
+ cd addtest &&
+ git submodule add -r "$submodurl" submod-record-head &&
+ test "$(git config -f .gitmodules submodule.submod-record-head.branch)" = "HEAD"
+ )
+'
+
+test_expect_success 'submodule add --record --branch' '
+ (
+ cd addtest &&
+ git submodule add -r -b initial "$submodurl" submod-auto-record &&
+ test "$(git config -f .gitmodules submodule.submod-auto-record.branch)" = "initial"
+ )
+'
+
+test_expect_success 'submodule add --record=<name> --branch' '
+ (
+ cd addtest &&
+ git submodule add -r=final -b initial "$submodurl" submod-record &&
+ test "$(git config -f .gitmodules submodule.submod-record.branch)" = "final"
+ )
+'
+
test_expect_success 'setup - add an example entry to .gitmodules' '
GIT_CONFIG=.gitmodules \
git config submodule.example.url git://example.com/init.git
--
1.8.0.1.g61a31f6.dirty
^ permalink raw reply related
* Re: [PATCH] git-submodule add: Record branch name in .gitmodules
From: Nahor @ 2012-10-23 22:02 UTC (permalink / raw)
To: git; +Cc: wking
In-Reply-To: <5086FFDC.2050700@web.de>
On 2012-10-23 13:36, Jens Lehmann wrote:
> Am 23.10.2012 21:16, schrieb Nahor:
>> Last issue, the branch that exists in your local repository may not
>> exist in someone else's repository, either because the branch is
>> purely local, or because it has a different name on the remote repo.
>
> You'll always face this kind of problems with commits too when using
> submodules, so I don't see that as a problem here.
Commits can't change or disappear during "normal" git operation (i.e.
without using "git push -f" or "git branch -D").
A commit also has the same id in all the clones repository so there is
no issue of a different name between the local and the remote repositories.
^ permalink raw reply
* Re: [PATCH] tile: support GENERIC_KERNEL_THREAD and GENERIC_KERNEL_EXECVE
From: Jeff King @ 2012-10-23 22:23 UTC (permalink / raw)
To: Marc Gauthier
Cc: Thomas Gleixner, Al Viro, Chris Metcalf, LKML,
linux-arch@vger.kernel.org, Linus Torvalds, Catalin Marinas,
git@vger.kernel.org, Junio C Hamano
In-Reply-To: <522C1DF17AF50042AD8AE87F7887BD3D0B60880C30@exch.hq.tensilica.com>
On Tue, Oct 23, 2012 at 03:06:59PM -0700, Marc Gauthier wrote:
> Can a later commit be eventually be made to reference some set
> of notes added so far, so they become part of the whole history
> signed by the HEAD SHA1? hence pulled/pushed automatically as
> well. Otherwise do you not end up with a forever growing separate
> tree of notes that loses some of the properties of being behind
> the head SHA1 (and perhaps less scalable in manageability)?
> Also that way notes are separate only temporarily.
Interesting idea. It would be tough to do with existing objects. There
are really only two ways for a commit to reference objects:
1. Via a parent header. But we would not want to include the notes
tree as a separate parent. The semantics are all wrong, and would
make your commit look like a nonsense merge.
2. As an entry in a tree. But we do not enforce connectivity of
commits referenced in trees, because that is the way that
submodules are implemented.
So I think we would have to add a new header that says "also, here are
some notes for my history". That has two problems:
1. It's not backwards compatible. People with the new version of git
will expect to have objects referenced by the new header, but older
servers may not provide those objects (and vice versa). We can add
a protocol extension to communicate this, but fundamentally you are
going to lose the object connection any time it passes through a
repo running an older git.
2. It's impure from the perspective of git's data model. Adding in the
notes reference is not really a property of the commit. It's more
like saying "Oh, these other things happened to _past_ commits, and
I'm just now mentioning them". So you pick an arbitrary commit to
attach it to. What are the semantics with relation to that commit's
position in the history graph? If I have a commit that is identical
but without the notes reference, it will have a different sha1. But
is it the same commit?
So it's a bit ugly. I think I'd rather build out the transfer
infrastructure to pass the notes references around more gracefully
without trying to shoehorn them into the commit graph.
> As for automating the inclusion of notes in the flow, can that
> be conditional on some pattern in the note, so that e.g. the
> Acked-by's get included and folded in automatically, whereas
> others do not, according to settings?
Yeah. You can store arbitrary data in notes (e.g., one of the existing
uses of notes is to record metadata on the patch emails that led to a
commit). Right now you typically separate it out by data type into
separate refs, and then you ask git log to show you particular ones (so
we see refs/notes/commits with "--notes", but you can do "--notes=foo"
to see refs/notes/foo, or even show multiple refs).
For the fold-on-rebase idea, I'd think you would want something similar,
like setting rebase.foldNotes to "foo" to say "refs/notes/foo contains
pseudo-headers that should be folded in like a signed-off-by".
-Peff
^ permalink raw reply
* [PATCH 0/8] fix git-config with duplicate variable entries
From: Jeff King @ 2012-10-23 22:35 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason; +Cc: Git Mailing List, Junio C Hamano
In-Reply-To: <CACBZZX5mOb7_i9r8AqNK5V3r-gVnzN+rkeY9xrhecGv1rS-anA@mail.gmail.com>
On Tue, Oct 23, 2012 at 04:13:44PM +0200, Ævar Arnfjörð Bjarmason wrote:
> > It fails a few tests in t1300, but it looks like those tests are testing
> > for the behavior we have identified as wrong, and should be fixed.
>
> I think this patch looks good.
Thanks. It had a few minor flaws (like a memory leak). I fixed those,
updated the tests, and split it out into a few more readable commits. In
the process, I managed to uncover and fix a few other memory leaks in
the area. I think this version is much more readable, and writing the
rationale for patch 7 convinced me that it's the right thing to do.
Another round of review would be appreciated.
[1/8]: t1300: style updates
[2/8]: t1300: remove redundant test
[3/8]: t1300: test "git config --get-all" more thoroughly
[4/8]: git-config: remove memory leak of key regexp
[5/8]: git-config: fix regexp memory leaks on error conditions
[6/8]: git-config: collect values instead of immediately printing
[7/8]: git-config: do not complain about duplicate entries
[8/8]: git-config: use git_config_with_options
For those just joining us, the interesting bit is patch 7, which fixes
some inconsistencies between the "git-config" tool and how the internal
config callbacks work.
> One other thing I think is worth clarifying (and I think should be
> broken) is if you write a configuration like:
>
> [foo]
> bar = one
> [foo]
> bar = two
> [foo]
> bar = three
>
> "git-{config,var} -l" will both give you:
>
> foo.bar=one
> foo.bar=two
> foo.bar=three
Yes, that looks right.
> And git config --get foo.bar will give you:
>
> $ git config -f /tmp/test --get foo.bar
> one
> error: More than one value for the key foo.bar: two
> error: More than one value for the key foo.bar: three
>
> I think that it would be better if the config mechanism just silently
> overwrote keys that clobbered earlier keys like your patch does.
Right.
> But in addition can we simplify things for the consumers of
> "git-{config,var} -l" by only printing:
>
> foo.bar=three
>
> Or are there too many variables like "include.path" that can
> legitimately appear more than once.
No. Some variables can legitimately appear multiple times. E.g.,
remote.*.fetch, remote.*.push, and remote.*.url. Probably more that I am
forgetting. There are not many, but they do exist.
It's OK to tweak the regular "get" for them, since they are already
broken for that case[1]. You need to use "--get-all" if you expect the
variable to have multiple values. But when we are listing, we do not
have the hint as to what is expected, and we need to show all entries.
-Peff
[1] So the one useful thing that the current duplicate check is doing is
flagging errors where you wanted to use --get-all, but forgot to.
However, it's not really a sufficient safeguard anyway, since it
would not catch cases where the list was split across multiple
files (which does work with the internal callbacks that handle
lists, since they never even see that multiple files are involved).
It's much more important for git-config to be consistent with the
internal parsing behavior.
^ permalink raw reply
* [PATCH 1/8] t1300: style updates
From: Jeff King @ 2012-10-23 22:35 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason; +Cc: Git Mailing List, Junio C Hamano
In-Reply-To: <20121023223502.GA23194@sigill.intra.peff.net>
The t1300 test script is quite old, and does not use our
modern techniques or styles. This patch updates it in the
following ways:
1. Use test_cmp instead of cmp (to make failures easier to
debug).
2. Use test_cmp instead of 'test $(command) = expected'.
This makes failures much easier to debug, and also
makes sure that $(command) exits appropriately.
3. Write tests with the usual style of:
test_expect_success 'test name' '
test commands &&
...
'
rather than one-liners, or using backslash-continuation.
This is purely a style fixup.
There are still a few command happening outside of
test_expect invocations, but they are all innoccuous system
commands like "cat" and "cp". In an ideal world, each test
would be self sufficient and all commands would happen
inside test_expect, but it is not immediately obvious how
the grouping should work (some of the commands impact the
subsequent tests, and some of them are setting up and
modifying state that many tests depend on). This patch just
picks the low-hanging style fruit, and we can do more fixes
on top later.
Signed-off-by: Jeff King <peff@peff.net>
---
t/t1300-repo-config.sh | 185 ++++++++++++++++++++++++++++++-------------------
1 file changed, 113 insertions(+), 72 deletions(-)
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index e127f35..e12dd4a 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -55,11 +55,13 @@ test_expect_success 'replace with non-match' \
test_cmp expect .git/config
'
-test_expect_success 'replace with non-match' \
- 'git config core.penguin kingpin !blue'
+test_expect_success 'replace with non-match' '
+ git config core.penguin kingpin !blue
+'
-test_expect_success 'replace with non-match (actually matching)' \
- 'git config core.penguin "very blue" !kingpin'
+test_expect_success 'replace with non-match (actually matching)' '
+ git config core.penguin "very blue" !kingpin
+'
cat > expect << EOF
[core]
@@ -108,8 +110,9 @@ EOF
lines
EOF
-test_expect_success 'unset with cont. lines' \
- 'git config --unset beta.baz'
+test_expect_success 'unset with cont. lines' '
+ git config --unset beta.baz
+'
cat > expect <<\EOF
[alpha]
@@ -133,8 +136,9 @@ cp .git/config .git/config2
cp .git/config .git/config2
-test_expect_success 'multiple unset' \
- 'git config --unset-all beta.haha'
+test_expect_success 'multiple unset' '
+ git config --unset-all beta.haha
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -145,7 +149,9 @@ EOF
[nextSection] noNewline = ouch
EOF
-test_expect_success 'multiple unset is correct' 'test_cmp expect .git/config'
+test_expect_success 'multiple unset is correct' '
+ test_cmp expect .git/config
+'
cp .git/config2 .git/config
@@ -156,8 +162,9 @@ rm .git/config2
rm .git/config2
-test_expect_success '--replace-all' \
- 'git config --replace-all beta.haha gamma'
+test_expect_success '--replace-all' '
+ git config --replace-all beta.haha gamma
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -169,7 +176,9 @@ EOF
[nextSection] noNewline = ouch
EOF
-test_expect_success 'all replaced' 'test_cmp expect .git/config'
+test_expect_success 'all replaced' '
+ test_cmp expect .git/config
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -200,7 +209,11 @@ test_expect_success 'really really mean test' '
test_cmp expect .git/config
'
-test_expect_success 'get value' 'test alpha = $(git config beta.haha)'
+test_expect_success 'get value' '
+ echo alpha >expect &&
+ git config beta.haha >actual &&
+ test_cmp expect actual
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -231,18 +244,21 @@ test_expect_success 'ambiguous get' '
test_cmp expect .git/config
'
-test_expect_success 'non-match' \
- 'git config --get nextsection.nonewline !for'
+test_expect_success 'non-match' '
+ git config --get nextsection.nonewline !for
+'
-test_expect_success 'non-match value' \
- 'test wow = $(git config --get nextsection.nonewline !for)'
+test_expect_success 'non-match value' '
+ test wow = $(git config --get nextsection.nonewline !for)
+'
test_expect_success 'ambiguous get' '
test_must_fail git config --get nextsection.nonewline
'
-test_expect_success 'get multivar' \
- 'git config --get-all nextsection.nonewline'
+test_expect_success 'get multivar' '
+ git config --get-all nextsection.nonewline
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -290,8 +306,9 @@ test_expect_success 'correct key' 'git config 123456.a123 987'
test_expect_success 'correct key' 'git config 123456.a123 987'
-test_expect_success 'hierarchical section' \
- 'git config Version.1.2.3eX.Alpha beta'
+test_expect_success 'hierarchical section' '
+ git config Version.1.2.3eX.Alpha beta
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -307,7 +324,9 @@ EOF
Alpha = beta
EOF
-test_expect_success 'hierarchical section value' 'test_cmp expect .git/config'
+test_expect_success 'hierarchical section value' '
+ test_cmp expect .git/config
+'
cat > expect << EOF
beta.noindent=sillyValue
@@ -316,9 +335,10 @@ EOF
version.1.2.3eX.alpha=beta
EOF
-test_expect_success 'working --list' \
- 'git config --list > output && cmp output expect'
-
+test_expect_success 'working --list' '
+ git config --list > output &&
+ test_cmp expect output
+'
cat > expect << EOF
EOF
@@ -332,8 +352,9 @@ EOF
nextsection.nonewline wow2 for me
EOF
-test_expect_success '--get-regexp' \
- 'git config --get-regexp in > output && cmp output expect'
+test_expect_success '--get-regexp' '
+ git config --get-regexp in > output && test_cmp expect output
+'
cat > expect << EOF
wow2 for me
@@ -353,41 +374,47 @@ echo false > expect
variable =
EOF
-test_expect_success 'get variable with no value' \
- 'git config --get novalue.variable ^$'
+test_expect_success 'get variable with no value' '
+ git config --get novalue.variable ^$
+'
-test_expect_success 'get variable with empty value' \
- 'git config --get emptyvalue.variable ^$'
+test_expect_success 'get variable with empty value' '
+ git config --get emptyvalue.variable ^$
+'
echo novalue.variable > expect
-test_expect_success 'get-regexp variable with no value' \
- 'git config --get-regexp novalue > output &&
- cmp output expect'
+test_expect_success 'get-regexp variable with no value' '
+ git config --get-regexp novalue > output &&
+ test_cmp expect output'
echo 'novalue.variable true' > expect
-test_expect_success 'get-regexp --bool variable with no value' \
- 'git config --bool --get-regexp novalue > output &&
- cmp output expect'
+test_expect_success 'get-regexp --bool variable with no value' '
+ git config --bool --get-regexp novalue > output &&
+ test_cmp expect output
+'
echo 'emptyvalue.variable ' > expect
-test_expect_success 'get-regexp variable with empty value' \
- 'git config --get-regexp emptyvalue > output &&
- cmp output expect'
+test_expect_success 'get-regexp variable with empty value' '
+ git config --get-regexp emptyvalue > output &&
+ test_cmp expect output
+'
echo true > expect
-test_expect_success 'get bool variable with no value' \
- 'git config --bool novalue.variable > output &&
- cmp output expect'
+test_expect_success 'get bool variable with no value' '
+ git config --bool novalue.variable > output &&
+ test_cmp expect output
+'
echo false > expect
-test_expect_success 'get bool variable with empty value' \
- 'git config --bool emptyvalue.variable > output &&
- cmp output expect'
+test_expect_success 'get bool variable with empty value' '
+ git config --bool emptyvalue.variable > output &&
+ test_cmp expect output
+'
test_expect_success 'no arguments, but no crash' '
test_must_fail git config >output 2>&1 &&
@@ -427,8 +454,9 @@ test_expect_success 'new variable inserts into proper section' '
test_cmp expect .git/config
'
-test_expect_success 'alternative GIT_CONFIG (non-existing file should fail)' \
- 'test_must_fail git config --file non-existing-config -l'
+test_expect_success 'alternative GIT_CONFIG (non-existing file should fail)' '
+ test_must_fail git config --file non-existing-config -l
+'
cat > other-config << EOF
[ein]
@@ -444,8 +472,10 @@ test_expect_success 'alternative GIT_CONFIG' '
test_cmp expect output
'
-test_expect_success 'alternative GIT_CONFIG (--file)' \
- 'git config --file other-config -l > output && cmp output expect'
+test_expect_success 'alternative GIT_CONFIG (--file)' '
+ git config --file other-config -l > output &&
+ test_cmp expect output
+'
test_expect_success 'refer config from subdirectory' '
mkdir x &&
@@ -489,8 +519,9 @@ EOF
weird
EOF
-test_expect_success "rename section" \
- "git config --rename-section branch.eins branch.zwei"
+test_expect_success 'rename section' '
+ git config --rename-section branch.eins branch.zwei
+'
cat > expect << EOF
# Hallo
@@ -503,17 +534,22 @@ test_expect_success "rename succeeded" "test_cmp expect .git/config"
weird
EOF
-test_expect_success "rename succeeded" "test_cmp expect .git/config"
+test_expect_success 'rename succeeded' '
+ test_cmp expect .git/config
+'
-test_expect_success "rename non-existing section" '
+test_expect_success 'rename non-existing section' '
test_must_fail git config --rename-section \
branch."world domination" branch.drei
'
-test_expect_success "rename succeeded" "test_cmp expect .git/config"
+test_expect_success 'rename succeeded' '
+ test_cmp expect .git/config
+'
-test_expect_success "rename another section" \
- 'git config --rename-section branch."1 234 blabl/a" branch.drei'
+test_expect_success 'rename another section' '
+ git config --rename-section branch."1 234 blabl/a" branch.drei
+'
cat > expect << EOF
# Hallo
@@ -526,14 +562,17 @@ EOF
weird
EOF
-test_expect_success "rename succeeded" "test_cmp expect .git/config"
+test_expect_success 'rename succeeded' '
+ test_cmp expect .git/config
+'
cat >> .git/config << EOF
[branch "vier"] z = 1
EOF
-test_expect_success "rename a section with a var on the same line" \
- 'git config --rename-section branch.vier branch.zwei'
+test_expect_success 'rename a section with a var on the same line' '
+ git config --rename-section branch.vier branch.zwei
+'
cat > expect << EOF
# Hallo
@@ -548,7 +587,9 @@ EOF
z = 1
EOF
-test_expect_success "rename succeeded" "test_cmp expect .git/config"
+test_expect_success 'rename succeeded' '
+ test_cmp expect .git/config
+'
test_expect_success 'renaming empty section name is rejected' '
test_must_fail git config --rename-section branch.zwei ""
@@ -562,7 +603,9 @@ EOF
[branch "zwei"] a = 1 [branch "vier"]
EOF
-test_expect_success "remove section" "git config --remove-section branch.zwei"
+test_expect_success 'remove section' '
+ git config --remove-section branch.zwei
+'
cat > expect << EOF
# Hallo
@@ -571,8 +614,9 @@ EOF
weird
EOF
-test_expect_success "section was removed properly" \
- "test_cmp expect .git/config"
+test_expect_success 'section was removed properly' '
+ test_cmp expect .git/config
+'
cat > expect << EOF
[gitcvs]
@@ -583,7 +627,6 @@ test_expect_success 'section ending' '
EOF
test_expect_success 'section ending' '
-
rm -f .git/config &&
git config gitcvs.enabled true &&
git config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite &&
@@ -593,7 +636,6 @@ test_expect_success numbers '
'
test_expect_success numbers '
-
git config kilo.gram 1k &&
git config mega.ton 1m &&
k=$(git config --int --get kilo.gram) &&
@@ -607,7 +649,6 @@ test_expect_success 'invalid unit' '
EOF
test_expect_success 'invalid unit' '
-
git config aninvalid.unit "1auto" &&
s=$(git config aninvalid.unit) &&
test "z1auto" = "z$s" &&
@@ -616,7 +657,7 @@ test_expect_success 'invalid unit' '
echo config should have failed
false
fi &&
- cmp actual expect
+ test_cmp actual expect
'
cat > expect << EOF
@@ -646,7 +687,7 @@ test_expect_success bool '
git config --bool --get bool.true$i >>result
git config --bool --get bool.false$i >>result
done &&
- cmp expect result'
+ test_cmp expect result'
test_expect_success 'invalid bool (--get)' '
@@ -680,7 +721,7 @@ test_expect_success 'set --bool' '
git config --bool bool.false2 "" &&
git config --bool bool.false3 nO &&
git config --bool bool.false4 FALSE &&
- cmp expect .git/config'
+ test_cmp expect .git/config'
cat > expect <<\EOF
[int]
@@ -695,7 +736,7 @@ test_expect_success 'set --int' '
git config --int int.val1 01 &&
git config --int int.val2 -1 &&
git config --int int.val3 5m &&
- cmp expect .git/config'
+ test_cmp expect .git/config'
cat >expect <<\EOF
[bool]
@@ -844,7 +885,7 @@ test_expect_success 'value continued on next line' '
test_expect_success 'value continued on next line' '
git config --list > result &&
- cmp result expect
+ test_cmp result expect
'
cat > .git/config <<\EOF
--
1.8.0.3.g3456896
^ permalink raw reply related
* [PATCH 2/8] t1300: remove redundant test
From: Jeff King @ 2012-10-23 22:36 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason; +Cc: Git Mailing List, Junio C Hamano
In-Reply-To: <20121023223502.GA23194@sigill.intra.peff.net>
This test checks that git-config fails for an ambiguous
"get", but we check the exact same thing 3 tests beforehand.
Signed-off-by: Jeff King <peff@peff.net>
---
I update the matching test later in the series, and I didn't want to
have to do it twice.
t/t1300-repo-config.sh | 4 ----
1 file changed, 4 deletions(-)
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index e12dd4a..c6489dc 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -275,10 +275,6 @@ test_expect_success 'multivar replace' '
test_cmp expect .git/config
'
-test_expect_success 'ambiguous value' '
- test_must_fail git config nextsection.nonewline
-'
-
test_expect_success 'ambiguous unset' '
test_must_fail git config --unset nextsection.nonewline
'
--
1.8.0.3.g3456896
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox