* Re: [PATCH 2/3] DWIM "git checkout frotz" to "git checkout -b frotz origin/frotz"
From: Nanako Shiraishi @ 2009-10-18 10:34 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Johannes Schindelin, Jay Soffian
In-Reply-To: <7vaazpxha4.fsf_-_@alter.siamese.dyndns.org>
Quoting Junio C Hamano <gitster@pobox.com>
> When 'frotz' is not a valid object name nor a tracked filename,
> we used to complain and failed this command. When there is only
> one remote that has 'frotz' as one of its tracking branches, we can
> DWIM it as a request to create a local branch 'frotz' forking from
> the matching remote tracking branch.
In the subject you used 'git checkout -b frotz origin/frotz'. Did you forget to say '-t'?
--
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/
^ permalink raw reply
* Re: [PATCH v3.1 3/5] Introduce new pretty formats %g[sdD] for reflog information
From: Nanako Shiraishi @ 2009-10-18 10:34 UTC (permalink / raw)
To: Jeff King; +Cc: Thomas Rast, Junio C Hamano, Jef Driesen, Nanako Shiraishi, git
In-Reply-To: <20091018071829.GA7748@coredump.intra.peff.net>
Quoting Jeff King <peff@peff.net>
> On Sat, Oct 17, 2009 at 04:48:11PM +0200, Thomas Rast wrote:
>
>> > +NOTE: Some placeholders may depend on other options given to the
>> > +revision traversal engine. For example, the `%g*` reflog options will
>> > +insert an empty string unless we are traversing reflog entries (e.g., by
>> > +`git log -g`). The `%d` placeholder will use the "short" decoration
>> > +format if `--decorate` was not already provided on the command line.
>>
>> Sure. I figured it was obvious enough, but since you already went to
>> the lengths of documenting the exact behaviour of %d, I squashed it
>> and adjusted the acknowledgement in the commit message accordingly.
>
> If the consensus (or Junio's decision when applying) is that we don't
> need it, I don't mind if my suggestion is scrapped (or reworded).
I think your clarification is a good addition.
--
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/
^ permalink raw reply
* Re: [PATCH 0/3] Generalized "string function" syntax
From: René Scharfe @ 2009-10-18 8:24 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v63ad5o8p.fsf@alter.siamese.dyndns.org>
Junio C Hamano schrieb:
> René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:
>
>> Junio C Hamano schrieb:
>>> I mentioned an idea to enhance the pretty=format language with a
>>> string function syntax that people can extend by adding new functions
>>> in one of the "What's cooking" messages earlier. The general syntax
>>> would be like
>>>
>>> %[function(args...)any string here%]
>>>
>>> where "any string here" part would have the usual pretty=format
>>> strings. E.g. git show -s --format='%{w(72,8,4)%s%+b%]' should give
>>> you a line wrapped commit log message if w(width,in1,in2) is such a
>>> function.
>> I pondered line wrapping with format strings briefly a long time ago, and
>> I always considered it to be more similar to a colour, i.e. a state that
>> one can change and that is applied to all following text until the next
>> state change. (Except that it's always reset at the end of the format
>> string.) The example above would then turn into '%w(72,8,4)%s%+b'.
>
> As a syntax to express "wrapping" behaviour alone, I think this is much
> simpler and more superiour. I guess with this if you want to wrap
> something to 72 columns and then wrap something else to 66 columns, you
> would write '%w(72,8,4)something%w(66,8,4)something else', right?
That's right.
> I used %] only for two reasons.
>
> - Without an explicit "here it ends", I couldn't come up with a good way
> to express '%[w(72,8,4)something%]something else'. IOW, how I can say
> "wrap something to 72 columns and then place something else without any
> wrapping"?
My patch makes '%w()' reset the wrapping parameters to their defaults.
> - When we need to support more than one string function like this, it is
> unclear what '%f()one string%g()another one' in your syntax means.
> Does it mean '%[f()one string%]%[g()another one%]' (i.e. concatenate
> the result of applying string function f to 'one string' and the result
> of applying string function g to 'another one')? Or does it mean
> '%[f()one string%[g()another one%]%]' (apply 'f' to concatenation of
> 'one string' and the result of applying 'g' to 'another one')?
I was going to say that we already have something like that with %C, and
that the natural way (to me) is to apply them both, independently. Case
modification functions (upper, lower, capitalized) could be treated the
same way -- as state changes (like pressing caps lock when typing text).
Which other text functions are we going to add which would break this
model? The only thing I can think of right now is nesting such
functions themselves, e.g. when indenting a list in an indented
sub-paragraph in an indented paragraph. Useful?
But then something else hit me: the line wrap function needs to consider
colour codes as having a length of zero. Ugh.
René
^ permalink raw reply
* [PATCH 3/3] git checkout --nodwim
From: Junio C Hamano @ 2009-10-18 8:01 UTC (permalink / raw)
To: git; +Cc: Johannes Schindelin, Jay Soffian
In-Reply-To: <7vzl7pyvzl.fsf@alter.siamese.dyndns.org>
Porcelains may want to make sure their calls to "git checkout" will
reliably fail regardless of the presense of random remote tracking
branches by the new DWIMmery introduced.
Luckily all existing in-tree callers have extra checks to make sure they
feed local branch name when they want to switch, or they explicitly ask
to detach HEAD at the given commit, so there is no need to add this option
for them.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin-checkout.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/builtin-checkout.c b/builtin-checkout.c
index fb7e68a..6ec9b83 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -616,6 +616,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
struct tree *source_tree = NULL;
char *conflict_style = NULL;
int patch_mode = 0;
+ int dwim_new_local_branch = 1;
struct option options[] = {
OPT__QUIET(&opts.quiet),
OPT_STRING('b', NULL, &opts.new_branch, "new branch", "branch"),
@@ -631,6 +632,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
OPT_STRING(0, "conflict", &conflict_style, "style",
"conflict style (merge or diff3)"),
OPT_BOOLEAN('p', "patch", &patch_mode, "select hunks interactively"),
+ OPT_SET_INT(0, "nodwim", &dwim_new_local_branch,
+ "do not dwim local branch creation", 0),
OPT_END(),
};
int has_dash_dash;
@@ -715,6 +718,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
if (has_dash_dash) /* case (1) */
die("invalid reference: %s", arg);
if (!patch_mode &&
+ dwim_new_local_branch &&
opts.track == BRANCH_TRACK_UNSPECIFIED &&
!opts.new_branch &&
!check_filename(NULL, arg) &&
--
1.6.5.1.95.g09fbd
^ permalink raw reply related
* [PATCH 2/3] DWIM "git checkout frotz" to "git checkout -b frotz origin/frotz"
From: Junio C Hamano @ 2009-10-18 8:01 UTC (permalink / raw)
To: git; +Cc: Johannes Schindelin, Jay Soffian
In-Reply-To: <7vzl7pyvzl.fsf@alter.siamese.dyndns.org>
When 'frotz' is not a valid object name nor a tracked filename,
we used to complain and failed this command. When there is only
one remote that has 'frotz' as one of its tracking branches, we can
DWIM it as a request to create a local branch 'frotz' forking from
the matching remote tracking branch.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin-checkout.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 57 insertions(+), 3 deletions(-)
diff --git a/builtin-checkout.c b/builtin-checkout.c
index d050c37..fb7e68a 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -572,6 +572,40 @@ static int interactive_checkout(const char *revision, const char **pathspec,
return run_add_interactive(revision, "--patch=checkout", pathspec);
}
+struct tracking_name_data {
+ const char *name;
+ char *remote;
+ int unique;
+};
+
+static int check_tracking_name(const char *refname, const unsigned char *sha1,
+ int flags, void *cb_data)
+{
+ struct tracking_name_data *cb = cb_data;
+ const char *slash;
+
+ if (prefixcmp(refname, "refs/remotes/"))
+ return 0;
+ slash = strchr(refname + 13, '/');
+ if (!slash || strcmp(slash + 1, cb->name))
+ return 0;
+ if (cb->remote) {
+ cb->unique = 0;
+ return 0;
+ }
+ cb->remote = xstrdup(refname);
+ return 0;
+}
+
+static const char *unique_tracking_name(const char *name)
+{
+ struct tracking_name_data cb_data = { name, NULL, 1 };
+ for_each_ref(check_tracking_name, &cb_data);
+ if (cb_data.unique)
+ return cb_data.remote;
+ free(cb_data.remote);
+ return NULL;
+}
int cmd_checkout(int argc, const char **argv, const char *prefix)
{
@@ -630,8 +664,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
opts.new_branch = argv0 + 1;
}
- if (opts.track == BRANCH_TRACK_UNSPECIFIED)
- opts.track = git_branch_track;
if (conflict_style) {
opts.merge = 1; /* implied */
git_xmerge_config("merge.conflictstyle", conflict_style, NULL);
@@ -655,6 +687,11 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
* With no paths, if <something> is a commit, that is to
* switch to the branch or detach HEAD at it.
*
+ * With no paths, if <something> is _not_ a commit, no -t nor -b
+ * was given, and there is a tracking branch whose name is
+ * <something> in one and only one remote, then this is a short-hand
+ * to fork local <something> from that remote tracking branch.
+ *
* Otherwise <something> shall not be ambiguous.
* - If it's *only* a reference, treat it like case (1).
* - If it's only a path, treat it like case (2).
@@ -677,7 +714,20 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
if (get_sha1(arg, rev)) {
if (has_dash_dash) /* case (1) */
die("invalid reference: %s", arg);
- goto no_reference; /* case (3 -> 2) */
+ if (!patch_mode &&
+ opts.track == BRANCH_TRACK_UNSPECIFIED &&
+ !opts.new_branch &&
+ !check_filename(NULL, arg) &&
+ argc == 1) {
+ const char *remote = unique_tracking_name(arg);
+ if (!remote || get_sha1(remote, rev))
+ goto no_reference;
+ opts.new_branch = arg;
+ arg = remote;
+ /* DWIMmed to create local branch */
+ }
+ else
+ goto no_reference;
}
/* we can't end up being in (2) anymore, eat the argument */
@@ -715,6 +765,10 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
}
no_reference:
+
+ if (opts.track == BRANCH_TRACK_UNSPECIFIED)
+ opts.track = git_branch_track;
+
if (argc) {
const char **pathspec = get_pathspec(prefix, argv);
--
1.6.5.1.95.g09fbd
^ permalink raw reply related
* [PATCH 1/3] check_filename(): make verify_filename() callable without dying
From: Junio C Hamano @ 2009-10-18 8:00 UTC (permalink / raw)
To: git; +Cc: Johannes Schindelin, Jay Soffian
In-Reply-To: <7vzl7pyvzl.fsf@alter.siamese.dyndns.org>
Make it possible to invole the logic of verify_filename() to make sure the
pathname arguments are unambiguous without actually dying. The caller may
want to do something different.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
cache.h | 1 +
setup.c | 38 ++++++++++++++++++++------------------
2 files changed, 21 insertions(+), 18 deletions(-)
diff --git a/cache.h b/cache.h
index 96840c7..71a731d 100644
--- a/cache.h
+++ b/cache.h
@@ -396,6 +396,7 @@ extern const char *setup_git_directory_gently(int *);
extern const char *setup_git_directory(void);
extern const char *prefix_path(const char *prefix, int len, const char *path);
extern const char *prefix_filename(const char *prefix, int len, const char *path);
+extern int check_filename(const char *prefix, const char *name);
extern void verify_filename(const char *prefix, const char *name);
extern void verify_non_filename(const char *prefix, const char *name);
diff --git a/setup.c b/setup.c
index 029371e..f67250b 100644
--- a/setup.c
+++ b/setup.c
@@ -61,6 +61,19 @@ const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
return path;
}
+int check_filename(const char *prefix, const char *arg)
+{
+ const char *name;
+ struct stat st;
+
+ name = prefix ? prefix_filename(prefix, strlen(prefix), arg) : arg;
+ if (!lstat(name, &st))
+ return 1; /* file exists */
+ if (errno == ENOENT || errno == ENOTDIR)
+ return 0; /* file does not exist */
+ die_errno("failed to stat '%s'", arg);
+}
+
/*
* Verify a filename that we got as an argument for a pathspec
* entry. Note that a filename that begins with "-" never verifies
@@ -70,18 +83,12 @@ const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
*/
void verify_filename(const char *prefix, const char *arg)
{
- const char *name;
- struct stat st;
-
if (*arg == '-')
die("bad flag '%s' used after filename", arg);
- name = prefix ? prefix_filename(prefix, strlen(prefix), arg) : arg;
- if (!lstat(name, &st))
+ if (check_filename(prefix, arg))
return;
- if (errno == ENOENT)
- die("ambiguous argument '%s': unknown revision or path not in the working tree.\n"
- "Use '--' to separate paths from revisions", arg);
- die_errno("failed to stat '%s'", arg);
+ die("ambiguous argument '%s': unknown revision or path not in the working tree.\n"
+ "Use '--' to separate paths from revisions", arg);
}
/*
@@ -91,19 +98,14 @@ void verify_filename(const char *prefix, const char *arg)
*/
void verify_non_filename(const char *prefix, const char *arg)
{
- const char *name;
- struct stat st;
-
if (!is_inside_work_tree() || is_inside_git_dir())
return;
if (*arg == '-')
return; /* flag */
- name = prefix ? prefix_filename(prefix, strlen(prefix), arg) : arg;
- if (!lstat(name, &st))
- die("ambiguous argument '%s': both revision and filename\n"
- "Use '--' to separate filenames from revisions", arg);
- if (errno != ENOENT && errno != ENOTDIR)
- die_errno("failed to stat '%s'", arg);
+ if (!check_filename(prefix, arg))
+ return;
+ die("ambiguous argument '%s': both revision and filename\n"
+ "Use '--' to separate filenames from revisions", arg);
}
const char **get_pathspec(const char *prefix, const char **pathspec)
--
1.6.5.1.95.g09fbd
^ permalink raw reply related
* Re: [PATCH/RFC] builtin-checkout: suggest creating local branch when appropriate to do so
From: Junio C Hamano @ 2009-10-18 7:58 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Jay Soffian, git
In-Reply-To: <alpine.DEB.1.00.0910052314580.4985@pacific.mpi-cbg.de>
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> Actually, we should really think long and hard why we should not
> automatically check out the local branch "next" in that case.
While people were thinking long and hard, I've spent some quality time
having fun with these patches, and realized that if we limit the scope of
the change to make sure that we only change the behaviour of a case where
we refused to do anything, this is not even something we need to think
long nor hard after all.
At least from the maintainer's point of view, that is.
I on the other hand do agree that we need to think long and hard when it
comes to the matter of explaining this to the users, though. I couldn't
come up with a good (re-)ordering of the documentation to fit this new
"short-cut" into the manpage.
A three-patch series will follow shortly.
^ permalink raw reply
* Re: [PATCH v3.1 3/5] Introduce new pretty formats %g[sdD] for reflog information
From: Jeff King @ 2009-10-18 7:18 UTC (permalink / raw)
To: Thomas Rast; +Cc: Junio C Hamano, Jef Driesen, Nanako Shiraishi, git
In-Reply-To: <e0ab6923eb4057bcbc8e97980dad5e4a37e53067.1255790816.git.trast@student.ethz.ch>
On Sat, Oct 17, 2009 at 04:48:11PM +0200, Thomas Rast wrote:
> > +NOTE: Some placeholders may depend on other options given to the
> > +revision traversal engine. For example, the `%g*` reflog options will
> > +insert an empty string unless we are traversing reflog entries (e.g., by
> > +`git log -g`). The `%d` placeholder will use the "short" decoration
> > +format if `--decorate` was not already provided on the command line.
>
> Sure. I figured it was obvious enough, but since you already went to
> the lengths of documenting the exact behaviour of %d, I squashed it
> and adjusted the acknowledgement in the commit message accordingly.
If the consensus (or Junio's decision when applying) is that we don't
need it, I don't mind if my suggestion is scrapped (or reworded).
-Peff
^ permalink raw reply
* Re: [PATCH 0/3] Generalized "string function" syntax
From: Junio C Hamano @ 2009-10-18 4:18 UTC (permalink / raw)
To: René Scharfe; +Cc: git
In-Reply-To: <4ADA3153.7070606@lsrfire.ath.cx>
René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:
> Junio C Hamano schrieb:
>> I mentioned an idea to enhance the pretty=format language with a
>> string function syntax that people can extend by adding new functions
>> in one of the "What's cooking" messages earlier. The general syntax
>> would be like
>>
>> %[function(args...)any string here%]
>>
>> where "any string here" part would have the usual pretty=format
>> strings. E.g. git show -s --format='%{w(72,8,4)%s%+b%]' should give
>> you a line wrapped commit log message if w(width,in1,in2) is such a
>> function.
>
> I pondered line wrapping with format strings briefly a long time ago, and
> I always considered it to be more similar to a colour, i.e. a state that
> one can change and that is applied to all following text until the next
> state change. (Except that it's always reset at the end of the format
> string.) The example above would then turn into '%w(72,8,4)%s%+b'.
As a syntax to express "wrapping" behaviour alone, I think this is much
simpler and more superiour. I guess with this if you want to wrap
something to 72 columns and then wrap something else to 66 columns, you
would write '%w(72,8,4)something%w(66,8,4)something else', right?
I used %] only for two reasons.
- Without an explicit "here it ends", I couldn't come up with a good way
to express '%[w(72,8,4)something%]something else'. IOW, how I can say
"wrap something to 72 columns and then place something else without any
wrapping"?
- When we need to support more than one string function like this, it is
unclear what '%f()one string%g()another one' in your syntax means.
Does it mean '%[f()one string%]%[g()another one%]' (i.e. concatenate
the result of applying string function f to 'one string' and the result
of applying string function g to 'another one')? Or does it mean
'%[f()one string%[g()another one%]%]' (apply 'f' to concatenation of
'one string' and the result of applying 'g' to 'another one')?
^ permalink raw reply
* How to revert one of multiple merges
From: Bill Lear @ 2009-10-18 2:31 UTC (permalink / raw)
To: git
Branch A, B, C each have 20 commits, 0-19.
Branch v1.0.0 created, then merge of A, B, C performed.
After testing, we realize that the branch B is not ready for
production release and we'd like to remove it from branch
v1.0.0.
If I do
% git merge A B C
I get a single commit:
% git log -p
commit 1644a0b98c01869aa83e59aa41374c22098c47b6
[...]
Date: Fri Oct 16 09:52:32 2009 -0500
Merge branches 'A', 'B' and 'C' into v1.0.0
[20 x 3 commits]
If I do
% git merge A
% git merge B
% git merge C
Then:
% git log -p
commit 8946edd381384d0882221c87b5b3b7bf47127d70
[...]
Date: Sat Oct 17 21:28:36 2009 -0500
Merge branch 'B' into v1.0.0
commit 076ed422443e3684e564f7cae2b92e4538088ae6
[...]
Date: Sat Oct 17 21:28:35 2009 -0500
Merge branch 'A' into v1.0.0
but no "Merge branch 'C' into v1.0.0".
And so, I'm faced with git rebase -i posing some unanswerable questions
to our release manager. She cannot easily remove B from the merge after
doint either merge A B C, or merge A, merge B, merge C.
Can anyone help?
Bill
^ permalink raw reply
* [ANNOUNCE] GIT 1.6.5.1
From: Junio C Hamano @ 2009-10-18 1:04 UTC (permalink / raw)
To: git
The latest maintenance release GIT 1.6.5.1 is available at the
usual places:
http://www.kernel.org/pub/software/scm/git/
git-1.6.5.1.tar.{gz,bz2} (source tarball)
git-htmldocs-1.6.5.1.tar.{gz,bz2} (preformatted docs)
git-manpages-1.6.5.1.tar.{gz,bz2} (preformatted docs)
The RPM binary packages for a few architectures are found in:
RPMS/$arch/git-*-1.6.5.1-1.fc9.$arch.rpm (RPM)
GIT v1.6.5.1 Release Notes
==========================
Fixes since v1.6.5
------------------
* An corrupt pack could make codepath to read objects into an
infinite loop.
* Download throughput display was always shown in KiB/s but on fast links
it is more appropriate to show it in MiB/s.
* "git grep -f filename" used uninitialized variable and segfaulted.
* "git clone -b branch" gave a wrong commit object name to post-checkout
hook.
* "git pull" over http did not work on msys.
Other minor documentation updates are included.
----------------------------------------------------------------
Changes since v1.6.5 are as follows:
Björn Steinbrink (1):
clone: Supply the right commit hash to post-checkout when -b is used
Johannes Sixt (1):
remote-curl: add missing initialization of argv0_path
Junio C Hamano (1):
GIT 1.6.5.1
Matt Kraai (1):
grep: do not segfault when -f is used
Miklos Vajna (1):
git-stash documentation: mention default options for 'list'
Nicolas Pitre (1):
change throughput display units with fast links
Shawn O. Pearce (1):
sha1_file: Fix infinite loop when pack is corrupted
^ permalink raw reply
* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was
From: Julian Phillips @ 2009-10-17 22:28 UTC (permalink / raw)
To: Björn Steinbrink
Cc: Nicolas Pitre, Junio C Hamano, Daniel Barkalow, James Pickens,
Jeff King, Jay Soffian, Git Mailing List
In-Reply-To: <20091017174843.GA16251@atjola.homenet>
On Sat, 17 Oct 2009, Bj?rn Steinbrink wrote:
> On 2009.10.17 18:35:38 +0100, Julian Phillips wrote:
>> On Sat, 17 Oct 2009, Bj?rn Steinbrink wrote:
>>> Do you have multiple (annotated) tags for the same commit?
>>
>> Potentially, yes. Releasing isn't the only thing that requires
>> keeping track of things. It's even possible that the person
>> creating the newer tag doesn't yet know that a release tag has been
>> applied if the person who applied it hasn't yet pushed it back.
>
> OK, I'd consider that namespace pollution, as things like
> "this-version-sucks" doesn't seem like it show go into public repos, but
> anyway. If your release tags fix into a certain "unique" format, you
> could use describe with --match, like:
> git describe --match 'v[0-9]*'
Well - that only helps if we only ever build the release tags. Which
isn't the case. The other tags are there for similar purposes and also
should go into the version string - but only when they were the tag
checked out.
Is it really that unreasonable to want to know exactly what it was that
was checked out? It's one of the few things that I miss from Subversion.
--
Julian
---
printk(KERN_INFO MYNAM ": English readable SCSI-3 strings enabled :-)\n");
linux-2.6.6/drivers/message/fusion/mptbase.c
^ permalink raw reply
* Re: git submodules
From: Nanako Shiraishi @ 2009-10-17 22:30 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Git Mailing List, Steven Noonan, crawl-ref-discuss
In-Reply-To: <m3tyxydj8f.fsf@localhost.localdomain>
Quoting Jakub Narebski <jnareb@gmail.com>
> Steven Noonan <steven@uplinklabs.net> writes:
>
>> We're using git submodules for the contributing libraries. When I
>> commit changes to those contribs, it correctly shows in the parent
>> repository that those folders have different revisions than what's
>> currently committed. However, if someone pulls those changes, it
>> doesn't automatically update the contribs to match the committed
>> version. But doing a pull or merge _should_ update the working tree to
>> match the committed versions. It does with file data, so why not
>> update the submodules? Especially if the submodule revision matched
>> the committed version -before- the pull. Why are we forced into using
>> 'git submodule update'?
>
> Because you might want not to use most current version of submodule,
> so git-pull shouldn't update submodules by default. And because
> git-pull didn't learn --recursive option yet.
I don't think your description is correct. Steven is talking about what the command should do by default. If you checked out the current superproject, by default you should get the submodule that matches. If you don't want the most current version, you can checkout an older submodule yourself.
You may want to follow this discussion:
http://thread.gmane.org/gmane.comp.version-control.git/130155/focus=130330
After stating that he isn't against the idea to make it automatic, Junio describes what needs to be done for it to happen and what are the corner cases that needs to be treated with care.
--
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/
^ permalink raw reply
* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was
From: Julian Phillips @ 2009-10-17 22:19 UTC (permalink / raw)
To: Junio C Hamano
Cc: Björn Steinbrink, Daniel Barkalow, James Pickens, Jeff King,
Nicolas Pitre, Jay Soffian, git
In-Reply-To: <7vljj97w7u.fsf@alter.siamese.dyndns.org>
On Sat, 17 Oct 2009, Junio C Hamano wrote:
> Julian Phillips <julian@quantumfyre.co.uk> writes:
>
>>>> My interest in this thread is solely that it might provide a mechanism
>>>> to find out which tag was checked out.
>>>
>>> Hmm, what is lacking in "git describe HEAD" for that? I am not
>>> complaining that you might be asking for something that exists, but I _do_
>>> want to know if something that exists is not a satisfactory solution and
>>> if so how it can be improved.
>>
>> What is lacking is the "checked out" part. "git describe HEAD" will
>> tell me _a_ tag that matches the currently checked out state.
>> However, it makes no guarantee that it was the one I checked out. If
>> I tag the code with "v1.0.0", and a colleague later tags it with
>> "this_version_sucks", then when I check out and build the code for the
>> customer the version it reports could well be "this_version_sucks"
>> instead of "v1.0.0" ...
>
> I think I understand why you think showing what you gave to your last "git
> checkout" (e.g. "checkout origin/master" or "checkout v1.0.0") and using
> that as a build identification token is a good idea. But "origin/master"
> is a moving target---it depends on when you checked it out. describe uses
> tags and does not use branch heads for a good reason.
For my purposes the branch that I built from is much more useful than the
output from describe. Releases are always made from tags, but for builds
used in the lab it is generally much more useful to know which branch was
built directly rather than being able to find the exact commit that was
built.
> "v1.0.0" also is to a lessor degree, as you may have tagged v1.0.0 locally
> and somebody else also has used the tag for a different version, but a tag
> is far less likely to move due to social convention. "describe --long"
> would make sure this won't be an issue anyway, though.
For any particular release only one person is given the job of making the
release tag, so we don't have the problem of multiple instances of the
same tag - but we do need to make sure that the version output is the
correct tag.
--
Julian
---
Water, taken in moderation cannot hurt anybody.
-- Mark Twain
^ permalink raw reply
* Re: [PATCH 1/3] format_commit_message(): fix function signature
From: René Scharfe @ 2009-10-17 21:04 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <1255681702-5215-2-git-send-email-gitster@pobox.com>
Junio C Hamano schrieb:
> The format template string was declared as "const void *" for some unknown
> reason, even though it obviously is meant to be passed a string. Make it
> "const char *".
Yes. I seem to have introduced that type in commit 7b95089c, but I
can't see (even less remember) why. Also note that commit message and
header file call the parameter "template", while it's called "format" in
commit.c (where the function used to live back then). What was I thinking?
Thanks for cleaning up after me.
René
^ permalink raw reply
* Re: [PATCH 0/3] Generalized "string function" syntax
From: René Scharfe @ 2009-10-17 21:04 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <1255681702-5215-1-git-send-email-gitster@pobox.com>
Junio C Hamano schrieb:
> I mentioned an idea to enhance the pretty=format language with a
> string function syntax that people can extend by adding new functions
> in one of the "What's cooking" messages earlier. The general syntax
> would be like
>
> %[function(args...)any string here%]
>
> where "any string here" part would have the usual pretty=format
> strings. E.g. git show -s --format='%{w(72,8,4)%s%+b%]' should give
> you a line wrapped commit log message if w(width,in1,in2) is such a
> function.
I pondered line wrapping with format strings briefly a long time ago, and
I always considered it to be more similar to a colour, i.e. a state that
one can change and that is applied to all following text until the next
state change. (Except that it's always reset at the end of the format
string.) The example above would then turn into '%w(72,8,4)%s%+b'.
Here's a patch to implement this behaviour. It leaves the implementation
of the actual wrap function as an exercise to the reader, too. ;-)
pretty.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 66 insertions(+), 0 deletions(-)
diff --git a/pretty.c b/pretty.c
index f5983f8..33464f1 100644
--- a/pretty.c
+++ b/pretty.c
@@ -445,6 +445,7 @@ struct format_commit_context {
enum date_mode dmode;
unsigned commit_header_parsed:1;
unsigned commit_message_parsed:1;
+ size_t width, indent1, indent2;
/* These offsets are relative to the start of the commit message. */
struct chunk author;
@@ -458,6 +459,7 @@ struct format_commit_context {
struct chunk abbrev_commit_hash;
struct chunk abbrev_tree_hash;
struct chunk abbrev_parent_hashes;
+ size_t wrap_start;
};
static int add_again(struct strbuf *sb, struct chunk *chunk)
@@ -595,6 +597,44 @@ static void format_decoration(struct strbuf *sb, const struct commit *commit)
strbuf_addch(sb, ')');
}
+static void strbuf_wrap(struct strbuf *sb, size_t pos, size_t len,
+ size_t width, size_t indent1, size_t indent2)
+{
+ struct strbuf tmp = STRBUF_INIT;
+
+ if (!len)
+ return;
+ if (pos)
+ strbuf_add(&tmp, sb->buf, pos);
+
+ /* XXX: all that's missing is the wrapping code itself.. */
+ strbuf_addf(&tmp, "w(%u,%u,%u)[\n",
+ (unsigned)width, (unsigned)indent1, (unsigned)indent2);
+ strbuf_add(&tmp, sb->buf + pos, len);
+ strbuf_addstr(&tmp, "\n]");
+
+ if (pos + len < sb->len)
+ strbuf_add(&tmp, sb->buf + pos + len, sb->len - pos - len);
+ strbuf_swap(&tmp, sb);
+ strbuf_release(&tmp);
+}
+
+static void rewrap_message_tail(struct strbuf *sb,
+ struct format_commit_context *c,
+ size_t new_width, size_t new_indent1,
+ size_t new_indent2)
+{
+ if (c->width == new_width && c->indent1 == new_indent1 &&
+ c->indent2 == new_indent2)
+ return;
+ strbuf_wrap(sb, c->wrap_start, sb->len - c->wrap_start, c->width,
+ c->indent1, c->indent2);
+ c->wrap_start = sb->len;
+ c->width = new_width;
+ c->indent1 = new_indent1;
+ c->indent2 = new_indent2;
+}
+
static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
void *context)
{
@@ -645,6 +685,30 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
return 3;
} else
return 0;
+ case 'w':
+ if (placeholder[1] == '(') {
+ unsigned long width = 0, indent1 = 0, indent2 = 0;
+ char *next;
+ const char *start = placeholder + 2;
+ const char *end = strchr(start, ')');
+ if (!end)
+ return 0;
+ if (end > start) {
+ width = strtoul(start, &next, 10);
+ if (*next == ',') {
+ indent1 = strtoul(next + 1, &next, 10);
+ if (*next == ',') {
+ indent2 = strtoul(next + 1,
+ &next, 10);
+ }
+ }
+ if (*next != ')')
+ return 0;
+ }
+ rewrap_message_tail(sb, c, width, indent1, indent2);
+ return end - placeholder + 1;
+ } else
+ return 0;
}
/* these depend on the commit */
@@ -748,7 +812,9 @@ void format_commit_message(const struct commit *commit,
memset(&context, 0, sizeof(context));
context.commit = commit;
context.dmode = dmode;
+ context.wrap_start = sb->len;
strbuf_expand(sb, format, format_commit_item, &context);
+ rewrap_message_tail(sb, &context, 0, 0, 0);
}
static void pp_header(enum cmit_fmt fmt,
^ permalink raw reply related
* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was
From: Daniel Barkalow @ 2009-10-17 20:35 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Christoph Bartoschek, git
In-Reply-To: <7vr5t2h3do.fsf@alter.siamese.dyndns.org>
On Sat, 17 Oct 2009, Junio C Hamano wrote:
> Christoph Bartoschek <bartoschek@gmx.de> writes:
>
> [jc: added Daniel back to cc list; please do not cull the cc list without
> good reason]
>
> > Daniel Barkalow wrote:
> >
> >> The upshot of the messages should be:
> >>
> >> $ git checkout origin/master
> >> Since you can't actually change "origin/master" yourself, you'll just
> >> be sightseeing unless you create a local branch to hold new local work.
> >>
> >> $ git branch
> >> * (not a local branch, but "origin/master")
> >>
> >> $ git commit
> >> You've been sightseeing "origin/master". The commit can't change that
> >> value, so your commit isn't held in any branch. If you want to create
> >> a branch to hold it, here's how.
> > ...
> > But then I was not able to verify that the checkout indeed matched the
> > 1.3.0-beta. "git status" and "git branch" did not help here.
>
> This is not going to help you, but "git reflog" would have helped here.
>
> The reason my suggesting "git reflog" now won't help you is because the
> word "reflog" does not connect the question "how did I get here" unless
> and until you know git already; in other words, it is not your fault that
> you got lost, but it is showing a wart in the UI.
>
> If the question you were asking was "does the files I have in my work tree
> after issuing that scary checkout actually match origin/1.3.0-beta?", you
> could have asked that question in a more direct way, and the command to do
> so is "git diff origin/1.3.0-beta". I do not think this would be asking
> the user to be doing something unreasonably unintuitive.
>
> If the question you were asking was (and it was not, from the description
> of your experience, but you could be in that situation when you "return
> some weeks later") "how does the checked out history relate to 1.3.0-beta?",
> then there is a way to ask the question in a very direct way, and the
> command to do so is "git show-branch HEAD origin/1.3.0-beta" (or give the
> same argument to "gitk").
>
> Although it is not _so_ unreasonable to expect "git status" to show the
> information, I suspect it would not be practical. After all, whenever
> somebody is lost, everything is "status". For a person who is lost and
> does not know where in the history he is, it might be reasonable to expect
> "status" to give the relationship between your HEAD and some branch/tag,
> while for another person who was hit by "git gui" complaining that he has
> too many loose objects, it might be reasonable for him to expect "status"
> to give the number of loose objects in the repository. IOW, "status" is
> too broad a word and following the path to cram everything into "status"
> so that any new person who gets lost can get necessary infor from the
> command will unfortunately lead to insanity.
>
> The second item in the Daniel's transcript above may be an improvement but
> I think it is a wrong economy to record and show 'but "origin/master"'
> (which cannot be correct forever and has to be invalidated once the user
> starts committing or resetting) in the message.
It's easy to invalidate it for reasons of the user going elsewhere: you
invalidate it when you invalidate MERGE_HEAD (which, incidentally,
locates a bug in my original patch: there's a third
"unlink(git_path("MERGE_HEAD"));" I didn't think of, in builtin-merge.c).
I think the case of it going stale, mainly due to updating a ref it uses,
is a matter of having whatever wants to describe HEAD check if the
extended sha1 still expands to the same sha1.
I also think that it fits with the git world model to distinguish
"lvalues" from "non-lvalues". An "lvalue" is something where you can make
a commit and change the value while the expression stays the same; you can
assign to it. If your current position is not an "lvalue" and you commit,
your current position must become a new temporary "lvalue", diverging from
the thing you can't change. But if you don't assign to it, there's no
problem with having a non-lvalue be your current position.
> I am wondering if a similar effect to help new users can be had by
> rewording the message to:
>
> $ git branch
> * (not a local branch; see "git reflog" to learn how you got here)
>
> The user can see how he got there even after doing something else after
> the checkout (see Nico's write-up in $gmane/130527). The difference is
> between giving fish and teaching how to catch one himself.
The reflog hint is a good one in general; on the other hand, I think it
would be generally helpful to have the information in a more
machine-readable fashion, for a "git checkout (whatever I gave to reset or
checkout before)".
Perhaps the right implementation is actually to have machine-readable
descriptions in the HEAD reflog? That would actually lead to the
interesting:
$ git checkout topic
$ git checkout origin/master
$ git checkout HEAD@{1}
$ git branch
* topic
Actually, we turn out to have a flaw in our reflog explanation: when
rebase finishes, it doesn't log that it's back to a particular branch.
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply
* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was
From: Björn Steinbrink @ 2009-10-17 19:41 UTC (permalink / raw)
To: Junio C Hamano
Cc: Julian Phillips, Daniel Barkalow, James Pickens, Jeff King,
Nicolas Pitre, Jay Soffian, git
In-Reply-To: <7vaazqcry5.fsf@alter.siamese.dyndns.org>
On 2009.10.17 02:04:02 -0700, Junio C Hamano wrote:
> The "save" part of the work-save-then-merge sequence should be made very
> visible to help people get used to the "not up, but work-save-then-merge"
> mental model. I do not think it would help people in the long run to make
> the "save" step less visible by wrapping the sequence into an unreliable
> "up" script, especially because the script would sometimes work but other
> times *has to* force users to know that what is happening behind the scene
> is work-save-then-merge in order to resolve and recover from conflicts
> anyway.
Hm, which cases would that be? I basically see three cases:
1) No uncommitted changes => No problem
2) Uncommitted changes merge cleanly => No problem
3) Uncommitted changes causes conflicts =>
- User can resolve
- User can start over (git update --retry)
- User can give up (git update --abort)
Of course the user can clearly see that some state was saved (otherwise
you couldn't retry or abort), but I don't see how the user is "forced"
in any way, he just gets those two commands to work with (which
internally just wrap reset + stash apply, making things more
convenient).
I do see problems with a "stash around merge" thing ("stash" around
rebase seems easier, as that could just create a commit and reset later,
but I'm not exactly sure that such smartness is a good idea). As soon as
the merge has conflicts, you need to know that you have to unstash after
committing the merge, but what I have in mind is fast-forward only (or
possibly reset, when upstream was rewritten). Primarily for users that
don't commit at all, but just look at things [*1*]. And also for the
semi-detached HEAD case, in which you may not commit and in which doing
a merge/rebase is therefore not an option, but git still knows what to
fetch/checkout by using the discussed extra info in HEAD, or by
examining the reflog.
> > OTOH, it might be easier to just tell the user to do the stash thing
> > himself. But I wonder how many users would really know how to get back
> > to the initial state then.
>
> I agree with the first sentence, but I do not understand what "the initial
> state" you talk about here in the second sentence, sorry.
The state they were in before they did the "git stash" part.
*work on stuff not ready to be committed*
git pull # refused
git stash
git pull
git stash apply # Conflicts, user decides that he wants go back
At that point, you need the reflog (also handle fast-forwards), and do:
git reset --hard HEAD@{1}
git stash apply --index
Of course, a more correct way might be to use commit and rebase instead:
*work on stuff not ready to be committed*
git pull # refused
git add -A # Or whatever
git commit
git pull --rebase # conflicts, decide to abort
git rebase --abort
git reset HEAD^
But that still needs the extra "reset HEAD^" step to really get back to
the state with your uncommitted changes.
The problem with "svn up" is that there's no other way, and no way back.
Git has other ways, but no convenient one for non-committers and no
"obvious" way to go back, should you decide that you actually prefer not
to update after seeing the conflicts.
Anyway, this isn't _my_ itch and to some (large) degree I'm trying to
guess what someone else would expect. If at all, I'm more interested in
a command that figures out which remote tracking branch I checked out,
and that updates it, and updates my work tree/index as well. Uncommitted
changes aren't important to me there. So I'll simply give up on that
part.
Björn
[*1*] One could also say: Users that don't give a damn about git, but
just need it to get the code and maybe have some minor, uncommitted
modifications on top. I'm _not_ thinking about users that actually
commit and do stuff. Those should use merge/rebase/pull, and get a
complaint from "git update" if the update is not a fast-forward one,
telling them what to use instead.
^ permalink raw reply
* [PATCH] Add the --submodule option to the diff option family
From: Jens Lehmann @ 2009-10-17 18:46 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Schindelin, Git Mailing List
When you use the option --submodule=left-right-log you can see the submodule
summaries inlined in the diff, instead of not-quite-helpful SHA-1 pairs.
The format imitates what "git submodule summary" shows.
To do that, <path>/.git/objects/ is added to the alternate object
databases (if that directory exists).
This option was requested by Jens Lehmann at the GitTogether in Berlin.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
---
In this patch i tried to address all the issues mentioned so far, please
let me know if anything is missing.
Documentation/diff-options.txt | 7 +++
Makefile | 2 +
diff.c | 16 ++++++
diff.h | 1 +
submodule.c | 112 ++++++++++++++++++++++++++++++++++++++++
submodule.h | 8 +++
6 files changed, 146 insertions(+), 0 deletions(-)
create mode 100644 submodule.c
create mode 100644 submodule.h
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 9276fae..99cb517 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -87,6 +87,13 @@ endif::git-format-patch[]
Show only names and status of changed files. See the description
of the `--diff-filter` option on what the status letters mean.
+--submodule[=<format>]::
+ Chose the output format for submodule differences. <format> can be one of
+ 'short' and 'left-right-log'. 'short' is the default value for this
+ option and and shows pairs of commit names. 'left-right-log' lists the
+ commits in that commit range like the 'summary' option of
+ linkgit:git-submodule[1] does.
+
--color::
Show colored diff.
diff --git a/Makefile b/Makefile
index c0eff64..2f61e17 100644
--- a/Makefile
+++ b/Makefile
@@ -453,6 +453,7 @@ LIB_H += sideband.h
LIB_H += sigchain.h
LIB_H += strbuf.h
LIB_H += string-list.h
+LIB_H += submodule.h
LIB_H += tag.h
LIB_H += transport.h
LIB_H += tree.h
@@ -551,6 +552,7 @@ LIB_OBJS += sideband.o
LIB_OBJS += sigchain.o
LIB_OBJS += strbuf.o
LIB_OBJS += string-list.o
+LIB_OBJS += submodule.o
LIB_OBJS += symlinks.o
LIB_OBJS += tag.o
LIB_OBJS += trace.o
diff --git a/diff.c b/diff.c
index c719ce2..8af1ae2 100644
--- a/diff.c
+++ b/diff.c
@@ -13,6 +13,7 @@
#include "utf8.h"
#include "userdiff.h"
#include "sigchain.h"
+#include "submodule.h"
#ifdef NO_FAST_WORKING_DIRECTORY
#define FAST_WORKING_DIRECTORY 0
@@ -1557,6 +1558,17 @@ static void builtin_diff(const char *name_a,
const char *a_prefix, *b_prefix;
const char *textconv_one = NULL, *textconv_two = NULL;
+ if (DIFF_OPT_TST(o, SUBMODULE_LEFT_RIGHT_LOG) &&
+ (!one->mode || S_ISGITLINK(one->mode)) &&
+ (!two->mode || S_ISGITLINK(two->mode))) {
+ const char *del = diff_get_color_opt(o, DIFF_FILE_OLD);
+ const char *add = diff_get_color_opt(o, DIFF_FILE_NEW);
+ show_submodule_summary(o->file, one ? one->path : two->path,
+ one->sha1, two->sha1,
+ del, add, reset);
+ return;
+ }
+
if (DIFF_OPT_TST(o, ALLOW_TEXTCONV)) {
textconv_one = get_textconv(one);
textconv_two = get_textconv(two);
@@ -2771,6 +2783,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
DIFF_OPT_CLR(options, ALLOW_TEXTCONV);
else if (!strcmp(arg, "--ignore-submodules"))
DIFF_OPT_SET(options, IGNORE_SUBMODULES);
+ else if (!prefixcmp(arg, "--submodule=")) {
+ if (!strcmp(arg + 12, "left-right-log"))
+ DIFF_OPT_SET(options, SUBMODULE_LEFT_RIGHT_LOG);
+ }
/* misc options */
else if (!strcmp(arg, "-z"))
diff --git a/diff.h b/diff.h
index a7e7ccb..8079f5b 100644
--- a/diff.h
+++ b/diff.h
@@ -67,6 +67,7 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
#define DIFF_OPT_DIRSTAT_BY_FILE (1 << 20)
#define DIFF_OPT_ALLOW_TEXTCONV (1 << 21)
#define DIFF_OPT_DIFF_FROM_CONTENTS (1 << 22)
+#define DIFF_OPT_SUBMODULE_LEFT_RIGHT_LOG (1 << 23)
#define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag)
#define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag)
#define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag)
diff --git a/submodule.c b/submodule.c
new file mode 100644
index 0000000..206386f
--- /dev/null
+++ b/submodule.c
@@ -0,0 +1,112 @@
+#include "cache.h"
+#include "submodule.h"
+#include "dir.h"
+#include "diff.h"
+#include "commit.h"
+#include "revision.h"
+
+int add_submodule_odb(const char *path)
+{
+ struct strbuf objects_directory = STRBUF_INIT;
+ struct alternate_object_database *alt_odb;
+
+ strbuf_addf(&objects_directory, "%s/.git/objects/", path);
+ if (!is_directory(objects_directory.buf))
+ return -1;
+
+ /* avoid adding it twice */
+ for (alt_odb = alt_odb_list; alt_odb; alt_odb = alt_odb->next)
+ if (alt_odb->name - alt_odb->base == objects_directory.len &&
+ !strncmp(alt_odb->base, objects_directory.buf,
+ objects_directory.len))
+ return 0;
+
+ alt_odb = xmalloc(objects_directory.len + 42 + sizeof(*alt_odb));
+ alt_odb->next = alt_odb_list;
+ strcpy(alt_odb->base, objects_directory.buf);
+ alt_odb->name = alt_odb->base + objects_directory.len;
+ alt_odb->name[2] = '/';
+ alt_odb->name[40] = '\0';
+ alt_odb->name[41] = '\0';
+ alt_odb_list = alt_odb;
+ prepare_alt_odb();
+ return 0;
+}
+
+void show_submodule_summary(FILE *f, const char *path,
+ unsigned char one[20], unsigned char two[20],
+ const char *del, const char *add, const char *reset)
+{
+ struct rev_info rev;
+ struct commit *commit, *left = left, *right;
+ struct commit_list *merge_bases, *list;
+ const char *message = NULL;
+ struct strbuf sb = STRBUF_INIT;
+ static const char *format = " %m %s";
+ int fast_forward = 0, fast_backward = 0;
+
+ if (is_null_sha1(two))
+ message = "(submodule deleted)";
+ else if (add_submodule_odb(path))
+ message = "(not checked out)";
+ else if (is_null_sha1(one))
+ message = "(new submodule)";
+ else if (!(left = lookup_commit_reference(one)) ||
+ !(right = lookup_commit_reference(two)))
+ message = "(commits not present)";
+
+ if (!message) {
+ init_revisions(&rev, NULL);
+ setup_revisions(0, NULL, &rev, NULL);
+ rev.left_right = 1;
+ rev.first_parent_only = 1;
+ left->object.flags |= SYMMETRIC_LEFT;
+ add_pending_object(&rev, &left->object, path);
+ add_pending_object(&rev, &right->object, path);
+ merge_bases = get_merge_bases(left, right, 1);
+ if (merge_bases) {
+ if (merge_bases->item == left)
+ fast_forward = 1;
+ else if (merge_bases->item == right)
+ fast_backward = 1;
+ }
+ for (list = merge_bases; list; list = list->next) {
+ list->item->object.flags |= UNINTERESTING;
+ add_pending_object(&rev, &list->item->object,
+ sha1_to_hex(list->item->object.sha1));
+ }
+ if (prepare_revision_walk(&rev))
+ message = "(revision walker failed)";
+ }
+
+ strbuf_addf(&sb, "Submodule %s %s..", path,
+ find_unique_abbrev(one, DEFAULT_ABBREV));
+ if (!fast_backward && !fast_forward)
+ strbuf_addch(&sb, '.');
+ strbuf_addf(&sb, "%s", find_unique_abbrev(two, DEFAULT_ABBREV));
+ if (message)
+ strbuf_addf(&sb, " %s\n", message);
+ else
+ strbuf_addf(&sb, "%s:\n", fast_backward ? " (rewind)" : "");
+ fwrite(sb.buf, sb.len, 1, f);
+
+ if (!message) {
+ while ((commit = get_revision(&rev))) {
+ strbuf_setlen(&sb, 0);
+ if (commit->object.flags & SYMMETRIC_LEFT) {
+ if (del)
+ strbuf_addstr(&sb, del);
+ }
+ else if (add)
+ strbuf_addstr(&sb, add);
+ format_commit_message(commit, format, &sb,
+ rev.date_mode);
+ if (reset)
+ strbuf_addstr(&sb, reset);
+ strbuf_addch(&sb, '\n');
+ fprintf(f, "%s", sb.buf);
+ }
+ clear_commit_marks(left, ~0);
+ clear_commit_marks(right, ~0);
+ }
+}
diff --git a/submodule.h b/submodule.h
new file mode 100644
index 0000000..4c0269d
--- /dev/null
+++ b/submodule.h
@@ -0,0 +1,8 @@
+#ifndef SUBMODULE_H
+#define SUBMODULE_H
+
+void show_submodule_summary(FILE *f, const char *path,
+ unsigned char one[20], unsigned char two[20],
+ const char *del, const char *add, const char *reset);
+
+#endif
--
1.6.5.3.g464e1.dirty
^ permalink raw reply related
* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was
From: Björn Steinbrink @ 2009-10-17 17:48 UTC (permalink / raw)
To: Julian Phillips
Cc: Nicolas Pitre, Junio C Hamano, Daniel Barkalow, James Pickens,
Jeff King, Jay Soffian, Git Mailing List
In-Reply-To: <alpine.LNX.2.00.0910171829430.7906@reaper.quantumfyre.co.uk>
On 2009.10.17 18:35:38 +0100, Julian Phillips wrote:
> On Sat, 17 Oct 2009, Bj?rn Steinbrink wrote:
> >Do you have multiple (annotated) tags for the same commit?
>
> Potentially, yes. Releasing isn't the only thing that requires
> keeping track of things. It's even possible that the person
> creating the newer tag doesn't yet know that a release tag has been
> applied if the person who applied it hasn't yet pushed it back.
OK, I'd consider that namespace pollution, as things like
"this-version-sucks" doesn't seem like it show go into public repos, but
anyway. If your release tags fix into a certain "unique" format, you
could use describe with --match, like:
git describe --match 'v[0-9]*'
> >Otherwise, I don't see why "git describe HEAD" should print the
> >wrong one. If there's a tag that can be resolved to the same
> >commit that HEAD can be resolved, then "git describe HEAD" must
> >output that one. Otherwise, that'd be a clear bug to me.
>
> Oh, definately no bug. git describe works exactly as expected, the
> problem is that the tag checked out isn't always the latest tag
> applied to that commit.
I misworded that one. Should be "If there's only tag that can be ...".
IOW it was meant for "only one tag per commit", which is what I assumed
to be the case.
Björn
^ permalink raw reply
* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was
From: Junio C Hamano @ 2009-10-17 17:43 UTC (permalink / raw)
To: Julian Phillips
Cc: Björn Steinbrink, Daniel Barkalow, James Pickens, Jeff King,
Nicolas Pitre, Jay Soffian, git
In-Reply-To: <alpine.LNX.2.00.0910171617580.6644@reaper.quantumfyre.co.uk>
Julian Phillips <julian@quantumfyre.co.uk> writes:
>>> My interest in this thread is solely that it might provide a mechanism
>>> to find out which tag was checked out.
>>
>> Hmm, what is lacking in "git describe HEAD" for that? I am not
>> complaining that you might be asking for something that exists, but I _do_
>> want to know if something that exists is not a satisfactory solution and
>> if so how it can be improved.
>
> What is lacking is the "checked out" part. "git describe HEAD" will
> tell me _a_ tag that matches the currently checked out state.
> However, it makes no guarantee that it was the one I checked out. If
> I tag the code with "v1.0.0", and a colleague later tags it with
> "this_version_sucks", then when I check out and build the code for the
> customer the version it reports could well be "this_version_sucks"
> instead of "v1.0.0" ...
I think I understand why you think showing what you gave to your last "git
checkout" (e.g. "checkout origin/master" or "checkout v1.0.0") and using
that as a build identification token is a good idea. But "origin/master"
is a moving target---it depends on when you checked it out. describe uses
tags and does not use branch heads for a good reason.
"v1.0.0" also is to a lessor degree, as you may have tagged v1.0.0 locally
and somebody else also has used the tag for a different version, but a tag
is far less likely to move due to social convention. "describe --long"
would make sure this won't be an issue anyway, though.
^ permalink raw reply
* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was
From: Junio C Hamano @ 2009-10-17 17:42 UTC (permalink / raw)
To: Björn Steinbrink
Cc: Junio C Hamano, Christoph Bartoschek, git, Daniel Barkalow
In-Reply-To: <20091017081901.GB5474@atjola.homenet>
Björn Steinbrink <B.Steinbrink@gmx.de> writes:
> On 2009.10.17 00:43:31 -0700, Junio C Hamano wrote:
>> Christoph Bartoschek <bartoschek@gmx.de> writes:
>> > Daniel Barkalow wrote:
>> >
>> >> The upshot of the messages should be:
>> >>
>> >> $ git checkout origin/master
>> >> Since you can't actually change "origin/master" yourself, you'll just
>> >> be sightseeing unless you create a local branch to hold new local work.
>> >>
>> >> $ git branch
>> >> * (not a local branch, but "origin/master")
>> >>
>> >> $ git commit
>> >> You've been sightseeing "origin/master". The commit can't change that
>> >> value, so your commit isn't held in any branch. If you want to create
>> >> a branch to hold it, here's how.
>
> [...]
>
>> The second item in the Daniel's transcript above may be an improvement but
>> I think it is a wrong economy to record and show 'but "origin/master"'
>> (which cannot be correct forever and has to be invalidated once the user
>> starts committing or resetting) in the message.
>
> I don't think it's entirely wrong to record that information, git just
> has to know when to invalidate it, possibly requiring the user to really
> detach HEAD.
Isn't it redundant information to begin with? See $gmane/130527
> git checkout origin/master
> git checkout origin/master~3
> git checkout HEAD^2~5
> git reset --hard HEAD~2
>
> Those commands are all about walking the ancestry of origin/master in
> some way. So it seems reasonable to assume that HEAD is still weakly
> bound to origin/master.
But as "walking" gets longer, the information will become less and less
relevant and at some point it becomes misleading. I cannot explain why
"let's take pains to maintain and carefully invalidate an extra piece of
redundant information so that we can show information the end user
shouldn't be trained to trust to begin with because it is unreliable" is a
good idea.
^ permalink raw reply
* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was
From: Julian Phillips @ 2009-10-17 17:35 UTC (permalink / raw)
To: Björn Steinbrink
Cc: Nicolas Pitre, Junio C Hamano, Daniel Barkalow, James Pickens,
Jeff King, Jay Soffian, Git Mailing List
In-Reply-To: <20091017170421.GA10490@atjola.homenet>
On Sat, 17 Oct 2009, Bj?rn Steinbrink wrote:
> On 2009.10.17 16:15:13 +0100, Julian Phillips wrote:
>> On Fri, 16 Oct 2009, Nicolas Pitre wrote:
>>
>>> On Fri, 16 Oct 2009, Julian Phillips wrote:
>>>
>>>> My interest in this thread is solely that it might provide a mechanism to find
>>>> out which tag was checked out. So, I'm just chucking in my $0.02 as a user.
>>>
>>> Try this:
>>>
>>> $ git checkout v1.5.5
>>> Note: moving to 'v1.5.5' which isn't a local branch
>>> If you want to create a new branch from this checkout, you may do so
>>> (now or later) by using -b with the checkout command again. Example:
>>> git checkout -b <new_branch_name>
>>> HEAD is now at 1d2375d... GIT 1.5.5
>>>
>>> [look around, and then ...]
>>>
>>> $ git checkout HEAD~2
>>> Previous HEAD position was 1d2375d... GIT 1.5.5
>>> HEAD is now at f61cc48... git-svn: fix following renamed paths when tracking a single path
>>>
>>> [go out for lunch ... and forget what this was about.]
>>>
>>> $ git reflog -3
>>> f61cc48 HEAD@{0}: checkout: moving from 1d2375d... to HEAD~2
>>> 1d2375d HEAD@{1}: checkout: moving from master to v1.5.5
>>> c274db7 HEAD@{2}: pull : Fast forward
>>>
>>> Here I have all the information to see what I did, and from what state.
>>> I even know that I did a pull on the master branch before moving away
>>> from it. The -3 limits the log to 3 entries. With no limit you get it
>>> all in your default pager.
>>>
>>> So there is no need for another mechanism to find out what tag was
>>> actually checked out -- you have it all already.
>>
>> What I want is a way for my build process to reliably know what
>> branch or tag is currently being built. "git symbolic-ref HEAD"
>> will give me the branch name, but doesn't work for tags. "git
>> describe" will find _a_ tag, but I can't tell if it's actually the
>> one checked out.
>
> Do you have multiple (annotated) tags for the same commit?
Potentially, yes. Releasing isn't the only thing that requires keeping
track of things. It's even possible that the person creating the newer
tag doesn't yet know that a release tag has been applied if the person
who applied it hasn't yet pushed it back.
> Otherwise, I don't see why "git describe HEAD" should print the wrong
> one. If there's a tag that can be resolved to the same commit that HEAD
> can be resolved, then "git describe HEAD" must output that one.
> Otherwise, that'd be a clear bug to me.
Oh, definately no bug. git describe works exactly as expected, the
problem is that the tag checked out isn't always the latest tag applied to
that commit.
--
Julian
---
Jayne: Shee-nio high tech Alliance crap!"
--Episode #9, "Ariel"
^ permalink raw reply
* Re: git submodules
From: Jakub Narebski @ 2009-10-17 17:27 UTC (permalink / raw)
To: Steven Noonan; +Cc: Git Mailing List, crawl-ref-discuss
In-Reply-To: <f488382f0910171015j1a6d4d9fg690867154334c514@mail.gmail.com>
Steven Noonan <steven@uplinklabs.net> writes:
> We're using git submodules for the contributing libraries. When I
> commit changes to those contribs, it correctly shows in the parent
> repository that those folders have different revisions than what's
> currently committed. However, if someone pulls those changes, it
> doesn't automatically update the contribs to match the committed
> version. But doing a pull or merge _should_ update the working tree to
> match the committed versions. It does with file data, so why not
> update the submodules? Especially if the submodule revision matched
> the committed version -before- the pull. Why are we forced into using
> 'git submodule update'?
Because you might want not to use most current version of submodule,
so git-pull shouldn't update submodules by default. And because
git-pull didn't learn --recursive option yet.
--
Jakub Narebski
Poland
ShadeHawk on #git
^ permalink raw reply
* git submodules
From: Steven Noonan @ 2009-10-17 17:15 UTC (permalink / raw)
To: Git Mailing List; +Cc: crawl-ref-discuss
One of the open source projects I work on (CC'd) recently moved to
git, but we're having some slight problems, and I believe that it's
the fault of git's UI in this case.
We're using git submodules for the contributing libraries. When I
commit changes to those contribs, it correctly shows in the parent
repository that those folders have different revisions than what's
currently committed. However, if someone pulls those changes, it
doesn't automatically update the contribs to match the committed
version. But doing a pull or merge _should_ update the working tree to
match the committed versions. It does with file data, so why not
update the submodules? Especially if the submodule revision matched
the committed version -before- the pull. Why are we forced into using
'git submodule update'?
- Steven
^ 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