* Re: [PATCH 2/5] branch: introduce --list argument
From: Junio C Hamano @ 2011-08-25 18:34 UTC (permalink / raw)
To: Michael J Gruber; +Cc: git, Junio C Hamano, Jeff King, Michael Schubert
In-Reply-To: <32d0954697da9ac96cc11af0d8cc1390d93fd037.1314259226.git.git@drmicha.warpmail.net>
Michael J Gruber <git@drmicha.warpmail.net> writes:
> Currently, there is no way to invoke the list mode with a pattern
> because this is interpreted as branch creation.
>
> Introduce a --list argument which invokes the list mode.
Probably this is --list "option", but I think this is a good idea to allow
"we are in list mode" without having to invoke "verbose" output.
^ permalink raw reply
* Re: [PATCH 1/5] branch: allow pattern arguments
From: Junio C Hamano @ 2011-08-25 18:32 UTC (permalink / raw)
To: Jeff King; +Cc: Michael J Gruber, git, Michael Schubert
In-Reply-To: <20110825175405.GD519@sigill.intra.peff.net>
Jeff King <peff@peff.net> writes:
> On Thu, Aug 25, 2011 at 10:30:17AM +0200, Michael J Gruber wrote:
>
>> - else if (argc == 0)
>> - return print_ref_list(kinds, detached, verbose, abbrev, with_commit);
>> + else if (argc == 0 || (verbose && argc == 1))
>> + return print_ref_list(kinds, detached, verbose, abbrev, with_commit, argc ? argv[0] : NULL);
>
> Note that "git tag -l" takes multiple patterns these days (it used to
> silently ignore everything after the first one!). "git branch" should
> probably do the same.
Agreed.
^ permalink raw reply
* Re* git clean --exclude broken?
From: Junio C Hamano @ 2011-08-25 18:29 UTC (permalink / raw)
To: git; +Cc: Todd Rinaldo
In-Reply-To: <7vfwkqmfsh.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> The documentation and the implementation of "git clean" is quite confused.
> ...
So here is a patch to fix the confusion.
It does not add a new "--except=C" I alluded to, but at least it should
be the right first step to make the document clearly describe what the
existing option does.
-- >8 --
Subject: [PATCH] Documentation: clarify "git clean -e <pattern>"
The current explanation of -e can be misread as allowing the user to say
I know 'git clean -XYZ' (substitute -XYZ with any option and/or
parameter) will remove paths A, B, and C, and I want them all removed
except for paths matching this pattern by adding '-e C' to the same
command line, i.e. 'git clean -e C -XYZ'.
But that is not what this option does. It augments the set of ignore rules
from the command line, just like the same "-e <pattern>" argument does
with the "ls-files" command (the user could probably pass "-e \!C" to tell
the command to clean everything the command would normally remove, except
for C).
It also fixes small style nit in the parameter to add_exclude() call. The
current code only works because EXC_CMDL happens to be defined as 0.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Documentation/git-clean.txt | 6 +++---
builtin/clean.c | 5 ++++-
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt
index 974e04e..a7a18e3 100644
--- a/Documentation/git-clean.txt
+++ b/Documentation/git-clean.txt
@@ -47,9 +47,9 @@ OPTIONS
-e <pattern>::
--exclude=<pattern>::
- Specify special exceptions to not be cleaned. Each <pattern> is
- the same form as in $GIT_DIR/info/excludes and this option can be
- given multiple times.
+ In addition to what are found in .gitignore (per directory) and
+ $GIT_DIR/info/exclude, also consider these patterns to be in the
+ set of the ignore rules in effect.
-x::
Don't use the ignore rules. This allows removing all untracked
diff --git a/builtin/clean.c b/builtin/clean.c
index 75697f7..3782718 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -76,6 +76,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
if (ignored && ignored_only)
die(_("-x and -X cannot be used together"));
+ if (ignored && exclude_list.nr)
+ die(_("adding exclude with -e and ignoring it with -x is crazy"));
if (!show_only && !force) {
if (config_set)
@@ -98,7 +100,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
setup_standard_excludes(&dir);
for (i = 0; i < exclude_list.nr; i++)
- add_exclude(exclude_list.items[i].string, "", 0, dir.exclude_list);
+ add_exclude(exclude_list.items[i].string, "", 0,
+ &dir.exclude_list[EXC_CMDL]);
pathspec = get_pathspec(prefix, argv);
^ permalink raw reply related
* Re: [PATCH] Do not allow refnames to start with a slash
From: Junio C Hamano @ 2011-08-25 18:17 UTC (permalink / raw)
To: Michael Haggerty; +Cc: git, cmn
In-Reply-To: <1314259695-30801-1-git-send-email-mhagger@alum.mit.edu>
Michael Haggerty <mhagger@alum.mit.edu> writes:
> diff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh
> index 1b0f82f..b05ca26 100755
> --- a/t/t1402-check-ref-format.sh
> +++ b/t/t1402-check-ref-format.sh
> @@ -18,6 +18,10 @@ invalid_ref 'foo'
> valid_ref 'foo/bar/baz'
> valid_ref 'refs///heads/foo'
> invalid_ref 'heads/foo/'
> +invalid_ref '/foo'
> +invalid_ref '/foo/bar'
As refs///heads/foo is defined to be valid_ref, I am moderately against
this change, which can break existing scripts.
> +invalid_ref 'foo/'
> +invalid_ref 'foo/bar/'
We already check trailing slash in existing checks, so I do not see a
point in these two additional lines.
> invalid_ref './foo'
> invalid_ref '.refs/foo'
> invalid_ref 'heads/foo..bar'
I was about to write "other than that the patch looks good", but then
realized there is nothing remaining after rejecting the new "now slash
cannot come at the beginning".
^ permalink raw reply
* Re: [RFC] branch: list branches by single remote
From: Junio C Hamano @ 2011-08-25 18:02 UTC (permalink / raw)
To: Thiago Farina; +Cc: Michael J Gruber, Michael Schubert, Jeff King, git
In-Reply-To: <CACnwZYd=pM+fRNy0pqv+jR9bb0AWC89nkgHq3m1nMw9cUfHOQw@mail.gmail.com>
Thiago Farina <tfransosi@gmail.com> writes:
> On Wed, Aug 24, 2011 at 3:34 PM, Junio C Hamano <gitster@pobox.com> wrote:
>> [Footnote]
>>
>> *1* It does not have to be a weekly _posting_ on the list but can be a
>> well-known Wiki page or even a bug tracker. Whatever medium is used for
>> this purpose, there _must_ be a built-in mechanism to expire entries away
>> that are inactive for more than some reasonable limit (say two to three
>> weeks).
>
> Host the project on Google Code for bug tracking? Use rietveld for
> code reviews (ike codereview.chromium.org and codereview.appspot.com)?
If any of the above expires entries by default unless explicit actions
are taken, I am personally fine to go with it.
^ permalink raw reply
* Re: [PATCH 1/5] branch: allow pattern arguments
From: Jeff King @ 2011-08-25 17:54 UTC (permalink / raw)
To: Michael J Gruber; +Cc: git, Junio C Hamano, Michael Schubert
In-Reply-To: <00847b8ee77129433a5d908ad25c9ebaf7fa7130.1314259226.git.git@drmicha.warpmail.net>
On Thu, Aug 25, 2011 at 10:30:17AM +0200, Michael J Gruber wrote:
> - else if (argc == 0)
> - return print_ref_list(kinds, detached, verbose, abbrev, with_commit);
> + else if (argc == 0 || (verbose && argc == 1))
> + return print_ref_list(kinds, detached, verbose, abbrev, with_commit, argc ? argv[0] : NULL);
Note that "git tag -l" takes multiple patterns these days (it used to
silently ignore everything after the first one!). "git branch" should
probably do the same.
-Peff
^ permalink raw reply
* Re: [PATCH 0/5] RFC: patterns for branch list
From: Jeff King @ 2011-08-25 17:53 UTC (permalink / raw)
To: Michael J Gruber; +Cc: git, Junio C Hamano, Michael Schubert
In-Reply-To: <cover.1314259226.git.git@drmicha.warpmail.net>
On Thu, Aug 25, 2011 at 10:30:16AM +0200, Michael J Gruber wrote:
> This mini series is about introducing patterns to the list mode of
> 'git branch' much like the pattern for 'git tag -l'. There are several
> related things which are to be considered for the ui design:
> [log vs tag vs branch]
I agree that the ideal UI change would be to move git-branch's "-l" to
"-g", and make "-l|--list" work the same as it does for git-tag.
Even though branch is generally considered a porcelain, I worry a little
about making that change. A script that wants to create a branch has no
real choice other than to use "git branch" (OK, they can use
"update-ref" themselves, but I seriously doubt that most scripts do so).
However, I kind of doubt anyone actually uses "-l"; it is mostly
pointless in the default config, so maybe it is safe.
Searching google code for "git.branch.*-l" turns up only one hit, and it
is somebody who apparently thought that "-l" meant "list".
> Analogous to "git tag", "branch" has several modes, one of which is list mode.
> It is currently activated (and possibly modified) by "-v" and "-vv", and when
> there are no arguments. So, at the least,
>
> git branch -v[v] <pattern>
>
> should match just like "git tag -l <pattern>" does. And that is what the first
> patch in my series does.
The order of your patches seems backwards to me. You add
pattern-matching for "-v", but there is no way to get pattern-matching
for the non-verbose case. Shouldn't "--list" come first?
Maybe I am just nitpicking, as I think the end result after the series
is the same. I just found the first patch very confusing.
> "git tag" should probably learn the same long option and others. And why not
> verify tags given by a pattern?
Yeah, having them both do --list makes sense. Whether it is appropriate
to glob for other operations, I don't know. I think you'd have to
look at each operation individually.
> Both "tag" and "branch" could activate list mode automatically on an invalid
> tag name rather than dieing:
>
> git tag v1.7.6\*
> Warning: tag 'v1.7.6*' not found.
> v1.7.6
> v1.7.6-rc0
> v1.7.6-rc1
> v1.7.6-rc2
> v1.7.6-rc3
> v1.7.6.1
That just seems confusing to me. What is the exit status? Shouldn't the
warning be "error: tag 'v1.7.6*' is not a valid tag name"?
> -v[v] sanity
> ============
>
> '-v' and '-vv' both take considerable time (because they need to walk).
> It makes more sense to have '-v' display cheap output (upstream name)
> and '-vv' add expensive output (ahead/behind info). '-vvv' could add super
> expensive info (ahead/equivalent/behind a la cherry-mark).
I think the original rationale was not so much "how much time does it
take", but rather "how much space do you want each line to take on your
terminal". For many people, the upstream name in "-vv" is just
cluttering noise.
Tag and branch listing are really just specialized versions of
for-each-ref. I wonder if it makes sense to do:
1. Teach for-each-ref formats replacement tokens for ahead/behind
counts.
2. Let the user specify a for-each-ref format for tag and branch
listing output. Then the various levels of "-v" just become some
special format strings, and the user is free to ask for whatever
they want (or even have "branch.defaultListFormat" to get it
without typing over and over).
-Peff
^ permalink raw reply
* Re: [PATCH v3] gitk: Allow commit editing
From: Jeff King @ 2011-08-25 17:30 UTC (permalink / raw)
To: Michal Sojka; +Cc: git, paulus
In-Reply-To: <87bovdvdhd.fsf@steelpick.2x.cz>
On Thu, Aug 25, 2011 at 03:15:42PM +0200, Michal Sojka wrote:
> I implemented something like you ontlined above (see below). Instead of
> rev-listing HEAD, I use the commit id to be edited. This way I don't
> have to find the commit in the returned list, but I only check whether
> the list is empty or not.
Yeah, that makes sense. Technically you are also rewriting every commit
_after_ the commit in question, so you want to be sure that those aren't
included elsewhere, too. But by definition, any ref which includes them
must also include the commit in question, so I think your test is
sufficient.
> Additionally, besides skiping HEAD ref, I also skip refs/stash. Rebasing
> before stash should not (I hope) cause any problems and therefore it is
> not necessary to warn the user.
Yes, that makes sense to me, too.
> > Speaking of which, notice that I used HEAD here. What happens with your
> > patch if I do:
> >
> > $ git checkout foo
> > $ gitk bar
> >
> > and select a commit to edit that is not in "foo"?
>
> I added a check for this. If this is detected, error message is
> displayed and no edit is possible.
I was going to suggest that we could actually do the rebase on "bar",
but that is probably too much complexity hiding behind the user's back
(not to mention that there are lots of corner cases where figuring out
the right branch is tough, like "gitk <sha1>").
> The other changes in this version are:
> - added --no-autosquash to rebase invocation
Yeah, that is probably a good idea.
> + # Check whether some other refs contain the commit to be edited
> + if {[exec git rev-list --stdin $id << $otherrefsneg] eq {}} {
> + if { [confirm_popup [mc "The commit you are going to edit is contained in another, possibly non-local, ref (e.g. branch or tag).\
> + It is a bad idea to change a ref that is possibly used by other people. See git-rebase(1) for details.\n\n\
> + Do you want to continue?"]]} {
> + return 1
Minor micro-optimization: this can be "git rev-list -1". You only care
if it produces the one commit, so that's sufficient. Without "-1", git
will keep reporting commits all the way down to the merge base with some
other ref.
Another question I had while thinking about whether or not this whole
idea is sane: what happens with conflicts in later commits that are
caused by your amended changes? Rebase will complain to the terminal,
no? Which the user may or may not even see, depending on how they
started gitk.
-Peff
^ permalink raw reply
* [PATCH] rev-list: Demonstrate breakage with --ancestry-path --all
From: Brad King @ 2011-08-25 16:49 UTC (permalink / raw)
To: git, gitster; +Cc: Heiko Voigt
In-Reply-To: <20110824213205.GI45292@book.hvoigt.net>
The option added by commit ebdc94f3 (revision: --ancestry-path,
2010-04-20) does not work properly in combination with --all, at least
in the case of a criss-cross merge:
b---bc
/ \ /
a X
\ / \
c---cb
There are no descendants of 'cb' in the history. The command
git rev-list --ancestry-path cb..bc
correctly reports no commits. However, the command
git rev-list --ancestry-path --all ^cb
reports 'bc'. Add a test case to t6019-rev-list-ancestry-path
demonstrating this breakage.
Signed-off-by: Brad King <brad.king@kitware.com>
---
I tried to fix the submodule merge search during a recursive merge by
only doing it when o->call_depth is zero. While testing the fix I
noticed that the merge search was reporting an incorrect commit as a
suggested submodule merge resolution. Internally the merge search uses
"rev-list --merges --ancestry-path --all ^a" to find all merges that
contain 'a'. The rev-list incorrectly reports the other side of the
criss-cross history. I narrowed the problem down to this test case.
Brad
t/t6019-rev-list-ancestry-path.sh | 35 +++++++++++++++++++++++++++++++++++
1 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/t/t6019-rev-list-ancestry-path.sh b/t/t6019-rev-list-ancestry-path.sh
index 7641029..aa4674f 100755
--- a/t/t6019-rev-list-ancestry-path.sh
+++ b/t/t6019-rev-list-ancestry-path.sh
@@ -70,4 +70,39 @@ test_expect_success 'rev-list --ancestry-patch D..M -- M.t' '
test_cmp expect actual
'
+# b---bc
+# / \ /
+# a X
+# \ / \
+# c---cb
+test_expect_success 'setup criss-cross' '
+ mkdir criss-cross &&
+ (cd criss-cross &&
+ git init &&
+ test_commit A &&
+ git checkout -b b master &&
+ test_commit B &&
+ git checkout -b c master &&
+ test_commit C &&
+ git checkout -b bc b -- &&
+ git merge c &&
+ git checkout -b cb c -- &&
+ git merge b &&
+ git checkout master)
+'
+
+# no commits in bc descend from cb
+test_expect_success 'criss-cross: rev-list --ancestry-path cb..bc' '
+ (cd criss-cross &&
+ git rev-list --ancestry-path cb..bc > actual &&
+ test -z "$(cat actual)")
+'
+
+# no commits in repository descend from cb
+test_expect_failure 'criss-cross: rev-list --ancestry-path --all ^cb' '
+ (cd criss-cross &&
+ git rev-list --ancestry-path --all ^cb > actual &&
+ test -z "$(cat actual)")
+'
+
test_done
--
1.7.4.4
^ permalink raw reply related
* Re: [PATCH] replace: List replacement along with the object
From: Christian Couder @ 2011-08-25 16:29 UTC (permalink / raw)
To: Michael J Gruber; +Cc: git, Junio C Hamano, Christian Couder
In-Reply-To: <bae5a8f7d30417864d972390f9f6b4470cf4e5bf.1314283118.git.git@drmicha.warpmail.net>
On Thu, Aug 25, 2011 at 4:39 PM, Michael J Gruber
<git@drmicha.warpmail.net> wrote:
> The documentation could be misunderstood as if "git replace -l" lists
> the replacements of the specified objects. Currently, it lists the
> replaced objects.
You could just change the documentation to make it more explicit.
> Change the output to the form "<object> <replacement>" so that there is
> an easy way to find the replacement, besides the more difficult to find
> git show-ref $(git replace -l).
I shamelessly copied the "-l <pattern>" feature and the documentation
from "git tag". If you just change the output of "git replace -l" it
will make the UI inconsistent between both commands.
Maybe you could add a "-L <pattern>" feature to "git replace", "git
tag" and "git branch" that would output "<ref name> <ref content>"?
Thanks,
Christian.
^ permalink raw reply
* Re: What's the difference between `git show branch:file | diff -u - file` vs `git diff branch file`?
From: Marat Radchenko @ 2011-08-25 16:09 UTC (permalink / raw)
To: Michael J Gruber, Junio C Hamano; +Cc: git
In-Reply-To: <4E54088F.7050700@drmicha.warpmail.net>
On 08/24/2011 00:07:43 MSD, Michael J Gruber <git@drmicha.warpmail.net> wrote:
> Junio C Hamano venit, vidit, dixit 23.08.2011 19:15:
> > Michael J Gruber <git@drmicha.warpmail.net> writes:
> >
> > > Marat Radchenko venit, vidit, dixit 23.08.2011 12:52:
> > > > > Is that a very large tree or a very slow file system?
> > > > Tree is large (500k files), file system is irrelevant since all
> > > > time is spend on CPU.
> > > >
> > > > > Do we enumerate all
> > > > > differing files and only then limit diff output by path??
> > > >
> > > > Dunno, that's why I am asking why it is so slow.
> > >
> > > Well, we have to read the full tree before diffing.
> >
> > Not necessarily, especially when pathspec is given like the original
> > post, i.e. "git diff $tree_ish -- $path". We would need to open tree
> > objects that lead to the leaf of the $path and a blob, but other
> > objects won't be needed.
>
> I meant: The way "git diff" is now, it does that.
>
> >
> > The default diff backend tries to come up with minimal changes by
> > spending extra cycles, so it is not so surprising if the file compared
> > is large-ish and/or has very many similar lines in itself (in which
> > case there are many potential matching line pairs between the preimage
> > and the postimage to be examined to produce a minimal diff).
>
> But the file in this case is not that large, and "git diff" spends 30s!
So, is some more info required from me or gprof output given in initial report + following discussion are enough to conclude what code needs to be improved?
^ permalink raw reply
* Re: [PATCH] vcs-svn: fix broken test 'keep content, but change mode'
From: Dmitry Ivankov @ 2011-08-25 16:08 UTC (permalink / raw)
To: git; +Cc: Jonathan Nieder, Ramkumar Ramachandra, Dmitry Ivankov, David Barr
In-Reply-To: <1314288124-16969-1-git-send-email-divanorama@gmail.com>
correct David's email (on first attempt I've accidentally used the old
one, taken from some git history)
On Thu, Aug 25, 2011 at 10:02 PM, Dmitry Ivankov <divanorama@gmail.com> wrote:
> svn symlinks are files with "link destination" content and a
> "svn:special=*" property set. These are imported as blobs with
> "destination" content and S_IFLNK mode. When svn copy a file without
> altering it's content(but maybe altering it's mode), we reuse the blob
> object thus loosing or not adding the "link " prefix.
>
> But we take possible prefix into account when applying svn deltas. And
> this is the only place we ask fast-import for original blob. So pretend
> that we want to apply a zero delta to resolve the issue.
>
> There is some overhead due to using a temporary file to store such a small
> blob. But hopefully such node change is too rare to care.
>
> Signed-off-by: Dmitry Ivankov <divanorama@gmail.com>
> ---
> This could be done better if we just read the cat-blob to memory, added or
> removed the "link " prefix and wrote it to the stream, because the link
> destination should be a tiny string. But on the other hand it'd blow up
> if for some reason it's huge.
>
> And taking into account that changing file mode from/to link without a
> content change should be extremely rare anyway, I think it's ok.
>
> Maybe it is redundant to add svndiff0_identity function to just cat blob
> to a temporary file. The excuse is that svndiff.c is the only user of this
> temporary file and the cat-blob response, so keep it there.
>
> The patch base is svn-fe branch at git://repo.or.cz/git/jrn.git
> Not backporting it to git master because vcs-svn stuff differs quite much
> around this change.
>
> t/t9010-svn-fe.sh | 2 +-
> vcs-svn/fast_export.c | 6 +++++-
> vcs-svn/svndiff.c | 17 +++++++++++++++++
> vcs-svn/svndiff.h | 1 +
> vcs-svn/svndump.c | 16 +++++++++++++++-
> 5 files changed, 39 insertions(+), 3 deletions(-)
>
> diff --git a/t/t9010-svn-fe.sh b/t/t9010-svn-fe.sh
> index b7eed24..b6bdfeb 100755
> --- a/t/t9010-svn-fe.sh
> +++ b/t/t9010-svn-fe.sh
> @@ -413,7 +413,7 @@ test_expect_success PIPE 'action: add node without text' '
> try_dump textless.dump must_fail
> '
>
> -test_expect_failure PIPE 'change file mode but keep old content' '
> +test_expect_success PIPE 'change file mode but keep old content' '
> reinit_git &&
> cat >expect <<-\EOF &&
> OBJID
> diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c
> index 19d7c34..8c7295f 100644
> --- a/vcs-svn/fast_export.c
> +++ b/vcs-svn/fast_export.c
> @@ -209,7 +209,11 @@ static long apply_delta(off_t len, struct line_buffer *input,
> preimage.max_off += strlen("link ");
> check_preimage_overflow(preimage.max_off, 1);
> }
> - if (svndiff0_apply(input, len, &preimage, out))
> +
> + if (!input) {
> + if (svndiff0_identity(&preimage, out))
> + die("cannot cat blob");
> + } else if (svndiff0_apply(input, len, &preimage, out))
> die("cannot apply delta");
> if (old_data) {
> /* Read the remainder of preimage and trailing newline. */
> diff --git a/vcs-svn/svndiff.c b/vcs-svn/svndiff.c
> index 9ee41bb..bf104db 100644
> --- a/vcs-svn/svndiff.c
> +++ b/vcs-svn/svndiff.c
> @@ -306,3 +306,20 @@ int svndiff0_apply(struct line_buffer *delta, off_t delta_len,
> }
> return 0;
> }
> +int svndiff0_identity(struct sliding_view *preimage, FILE *postimage)
> +{
> + assert(preimage && postimage);
> + off_t pre_off = 0;
> +
> + while (pre_off != preimage->max_off) {
> + size_t pre_len = 8192;
> + if (pre_off + pre_len > preimage->max_off)
> + pre_len = preimage->max_off - pre_off;
> + if (move_window(preimage, pre_off, pre_len) ||
> + write_strbuf(&preimage->buf, postimage))
> + return -1;
> + pre_off += pre_len;
> + }
> +
> + return 0;
> +}
> diff --git a/vcs-svn/svndiff.h b/vcs-svn/svndiff.h
> index 74eb464..5afa3f2 100644
> --- a/vcs-svn/svndiff.h
> +++ b/vcs-svn/svndiff.h
> @@ -6,5 +6,6 @@ struct sliding_view;
>
> extern int svndiff0_apply(struct line_buffer *delta, off_t delta_len,
> struct sliding_view *preimage, FILE *postimage);
> +extern int svndiff0_identity(struct sliding_view *preimage, FILE *postimage);
>
> #endif
> diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c
> index b1f4161..1e7ed48 100644
> --- a/vcs-svn/svndump.c
> +++ b/vcs-svn/svndump.c
> @@ -285,7 +285,21 @@ static void handle_node(void)
> /* For the fast_export_* functions, NULL means empty. */
> old_data = NULL;
> if (!have_text) {
> - fast_export_modify(node_ctx.dst.buf, node_ctx.type, old_data);
> + /*
> + * This is clean content copy in svn, but we alter the content
> + * of symlinks (add/remove "link " prefix used by svn). So when
> + * mode changes from/to symlink specify (recreate) data inline.
> + */
> + if (node_ctx.type != old_mode && (old_mode == REPO_MODE_LNK
> + || node_ctx.type == REPO_MODE_LNK)) {
> +
> + fast_export_modify(node_ctx.dst.buf,
> + node_ctx.type, "inline");
> + fast_export_blob_delta(node_ctx.type, old_mode,
> + old_data, 0, NULL);
> + } else
> + fast_export_modify(node_ctx.dst.buf,
> + node_ctx.type, old_data);
> return;
> }
> if (!node_ctx.text_delta) {
> --
> 1.7.3.4
>
>
^ permalink raw reply
* Re: master-master server setup
From: Sitaram Chamarty @ 2011-08-25 16:06 UTC (permalink / raw)
To: Drew Northup, Corey Mitchell; +Cc: git
In-Reply-To: <1314210406.14580.6.camel@drew-northup.unet.maine.edu>
[Thanks Drew!]
Corey,
On Wed, Aug 24, 2011 at 11:56 PM, Drew Northup <drew.northup@maine.edu> wrote:
>
> On Wed, 2011-08-24 at 17:14 +0000, Corey Mitchell wrote:
>> Hello Git team,
>>
>> We have a distributed team (US and Japan). We are thinking about migrating from
>> subversion to git because it better suits our distributed team. Due to network
>> latency, we want to setup 2 git servers hosting the same repository. We want
>> developers to be able to download and publish branches to their local server and
>> then have those changes replicated to the other site. Is this possible? Can
>> someone please explain how this setup is done? If not, can someone please
>> explain the closest alternative and how it is setup?
>
> Corey,
> If you choose to use gitolite, then you can just use Sitaram's
> instructions here:
> http://sitaramc.github.com/gitolite/doc/mirroring.html
The code for all this is in the "mirroring-revamp" branch, by the way,
although I hope to shortly bump it into pu (see below).
> If nothing else, you might find it inspirational.
Considering I spend more time on the docs than on the code, I sure
hope it's at least that ;-)
I'm currently at one of my $DAYJOB's other cities, setting up an
11-way mirrored gitolite setup for some colleagues in a different
business unit. They have about 80 repos spread across 6 or 7 cities,
which different repos being "mastered" at different cities.
Some of them have 2 slaves, most have 1. Of those that have 2 slaves,
only one needs the push *immediately* reflected. All of them have to
send to a specific "backup" server sometime at night so that's like an
extra slave, though developers are not expected to hit it so it
doesn't need any authorisation information..
Some have enough developers that for convenience reasons they would
like to have the developer push to the (local) slave and have the
slave internally redirect the push to the real master, without the
developer having to know where the real master is and having to
configure his push-remote correctly. For developers who're working on
multiple projects, with some of them mastered in one city and some in
another, this is great. (I must warn that this feature is only useful
when all the servers trust each others authentication, because that
gets done at the slave site where the user hit, and authorisation is
done on the real master taking the push).
Note that this does no do exactly what you said, but probably comes
close enough in some sense.
So anyway it's been fun. We're halfway there, and no problems so far.
Once this is up and running for a few days I will merge it into pu.
regards
sitaram
^ permalink raw reply
* Re: One MMORPG git facts
From: Marat Radchenko @ 2011-08-25 16:02 UTC (permalink / raw)
To: J.H.; +Cc: git
In-Reply-To: <4E560053.1080005@eaglescrag.net>
On 08/25/2011 11:57:07 MSD, J.H. <warthog9@eaglescrag.net> wrote:
> Given the differences, I'm morbidly curious, which actually ends up
> being the more usable version control system of a project of this scale?
> It sounds like (from what you've said) git is generally faster,
> assuming it can get enough resources (which can obviously be hard at the
> scales your talking).
Hard to compare (especially because I don't have pure git environment but git-svn clone). I have give you some
First, there are lots of non-geek people working on MMORPG (quest designers, modellers, text writers, map designers). Many of them find it hard to understand DVCS concepts and prefer living with linear history in a single branch (svn trunk). Their work is highly isolated from each other (for ex, maps are split in "regions" and only one person is allowed to edit one region simultanuously, only one modeller works on a particular model, each quest has a person responsible for it) so they don't hit conflicts as often as programmers do. And since svn up of whole tree takes 40 mins, they don't update during work day but have nightly script for that so the only thing they regularly use is svn commit.
Second, there's TortoiseSVN that allows easy (for non-geeks) GUI history inspection.
Third, we have 200 commits per day (8 work hours), that's one commit each 2.4 mins (actually, much less during lunch and much more in the morning caused by the fact that programmers are not allowed to commit after 16:00), so you copy is outdated all the time. If upstream repo was git, one would have to pull + push in those 2.4 mins, otherwise she would hit non-ff push. This could be fixed by using separate repos, though that would complicate git setup even more.
On the other hand, git is really great for programmers. Heck, svn still doesn't have anything like "git log -u" (well, afaik, they finally added it in 1.7)! Stash/bisect/local commits/history rewriting/cheap branching(almost no branching happens in svn repo because that either involves either fetching of 7Gb or [if svn switch is used] 10-30mins [don't remember exactly] of massive I/O. [sorry for two-level nesting]) are very handy on daily basis. Also, git allows easy sharing of experimental changes between programmers without touching shared server. It also allows atomic commits for the whole working copy (which is important when programmer changes server, client or data at the same time).
There are some decisions that were made and without which repo could be smaller (for example, client/server binaries are commited daily so that designers can use them on next day), however these decisions were made long before i joined the project and are very likely to stay this way.
To sum this up: git is a wonderful (and very powerful) tool for programmers but too complex for non-tech users.
^ permalink raw reply
* [PATCH] vcs-svn: fix broken test 'keep content, but change mode'
From: Dmitry Ivankov @ 2011-08-25 16:02 UTC (permalink / raw)
To: git; +Cc: Jonathan Nieder, David Barr, Ramkumar Ramachandra, Dmitry Ivankov
svn symlinks are files with "link destination" content and a
"svn:special=*" property set. These are imported as blobs with
"destination" content and S_IFLNK mode. When svn copy a file without
altering it's content(but maybe altering it's mode), we reuse the blob
object thus loosing or not adding the "link " prefix.
But we take possible prefix into account when applying svn deltas. And
this is the only place we ask fast-import for original blob. So pretend
that we want to apply a zero delta to resolve the issue.
There is some overhead due to using a temporary file to store such a small
blob. But hopefully such node change is too rare to care.
Signed-off-by: Dmitry Ivankov <divanorama@gmail.com>
---
This could be done better if we just read the cat-blob to memory, added or
removed the "link " prefix and wrote it to the stream, because the link
destination should be a tiny string. But on the other hand it'd blow up
if for some reason it's huge.
And taking into account that changing file mode from/to link without a
content change should be extremely rare anyway, I think it's ok.
Maybe it is redundant to add svndiff0_identity function to just cat blob
to a temporary file. The excuse is that svndiff.c is the only user of this
temporary file and the cat-blob response, so keep it there.
The patch base is svn-fe branch at git://repo.or.cz/git/jrn.git
Not backporting it to git master because vcs-svn stuff differs quite much
around this change.
t/t9010-svn-fe.sh | 2 +-
vcs-svn/fast_export.c | 6 +++++-
vcs-svn/svndiff.c | 17 +++++++++++++++++
vcs-svn/svndiff.h | 1 +
vcs-svn/svndump.c | 16 +++++++++++++++-
5 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/t/t9010-svn-fe.sh b/t/t9010-svn-fe.sh
index b7eed24..b6bdfeb 100755
--- a/t/t9010-svn-fe.sh
+++ b/t/t9010-svn-fe.sh
@@ -413,7 +413,7 @@ test_expect_success PIPE 'action: add node without text' '
try_dump textless.dump must_fail
'
-test_expect_failure PIPE 'change file mode but keep old content' '
+test_expect_success PIPE 'change file mode but keep old content' '
reinit_git &&
cat >expect <<-\EOF &&
OBJID
diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c
index 19d7c34..8c7295f 100644
--- a/vcs-svn/fast_export.c
+++ b/vcs-svn/fast_export.c
@@ -209,7 +209,11 @@ static long apply_delta(off_t len, struct line_buffer *input,
preimage.max_off += strlen("link ");
check_preimage_overflow(preimage.max_off, 1);
}
- if (svndiff0_apply(input, len, &preimage, out))
+
+ if (!input) {
+ if (svndiff0_identity(&preimage, out))
+ die("cannot cat blob");
+ } else if (svndiff0_apply(input, len, &preimage, out))
die("cannot apply delta");
if (old_data) {
/* Read the remainder of preimage and trailing newline. */
diff --git a/vcs-svn/svndiff.c b/vcs-svn/svndiff.c
index 9ee41bb..bf104db 100644
--- a/vcs-svn/svndiff.c
+++ b/vcs-svn/svndiff.c
@@ -306,3 +306,20 @@ int svndiff0_apply(struct line_buffer *delta, off_t delta_len,
}
return 0;
}
+int svndiff0_identity(struct sliding_view *preimage, FILE *postimage)
+{
+ assert(preimage && postimage);
+ off_t pre_off = 0;
+
+ while (pre_off != preimage->max_off) {
+ size_t pre_len = 8192;
+ if (pre_off + pre_len > preimage->max_off)
+ pre_len = preimage->max_off - pre_off;
+ if (move_window(preimage, pre_off, pre_len) ||
+ write_strbuf(&preimage->buf, postimage))
+ return -1;
+ pre_off += pre_len;
+ }
+
+ return 0;
+}
diff --git a/vcs-svn/svndiff.h b/vcs-svn/svndiff.h
index 74eb464..5afa3f2 100644
--- a/vcs-svn/svndiff.h
+++ b/vcs-svn/svndiff.h
@@ -6,5 +6,6 @@ struct sliding_view;
extern int svndiff0_apply(struct line_buffer *delta, off_t delta_len,
struct sliding_view *preimage, FILE *postimage);
+extern int svndiff0_identity(struct sliding_view *preimage, FILE *postimage);
#endif
diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c
index b1f4161..1e7ed48 100644
--- a/vcs-svn/svndump.c
+++ b/vcs-svn/svndump.c
@@ -285,7 +285,21 @@ static void handle_node(void)
/* For the fast_export_* functions, NULL means empty. */
old_data = NULL;
if (!have_text) {
- fast_export_modify(node_ctx.dst.buf, node_ctx.type, old_data);
+ /*
+ * This is clean content copy in svn, but we alter the content
+ * of symlinks (add/remove "link " prefix used by svn). So when
+ * mode changes from/to symlink specify (recreate) data inline.
+ */
+ if (node_ctx.type != old_mode && (old_mode == REPO_MODE_LNK
+ || node_ctx.type == REPO_MODE_LNK)) {
+
+ fast_export_modify(node_ctx.dst.buf,
+ node_ctx.type, "inline");
+ fast_export_blob_delta(node_ctx.type, old_mode,
+ old_data, 0, NULL);
+ } else
+ fast_export_modify(node_ctx.dst.buf,
+ node_ctx.type, old_data);
return;
}
if (!node_ctx.text_delta) {
--
1.7.3.4
^ permalink raw reply related
* [PATCH] update-ref: whitespace fix
From: pangyanhan @ 2011-08-25 15:40 UTC (permalink / raw)
To: git; +Cc: Pang Yan Han
From: Pang Yan Han <pangyanhan@gmail.com>
Signed-off-by: Pang Yan Han <pangyanhan@gmail.com>
---
builtin/update-ref.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 76ba1d5..835c62a 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -11,7 +11,7 @@ static const char * const git_update_ref_usage[] = {
int cmd_update_ref(int argc, const char **argv, const char *prefix)
{
- const char *refname, *oldval, *msg=NULL;
+ const char *refname, *oldval, *msg = NULL;
unsigned char sha1[20], oldsha1[20];
int delete = 0, no_deref = 0, flags = 0;
struct option options[] = {
--
1.7.6.1.385.gb7fcd0
^ permalink raw reply related
* [PATCHv2] log: Do not decorate replacements with --no-replace-objects
From: Michael J Gruber @ 2011-08-25 15:09 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy, Junio C Hamano
In-Reply-To: <4E566586.5010901@drmicha.warpmail.net>
5267d29 (log: decorate "replaced" on to replaced commits, 2011-08-19)
introduced textual decorations for replaced commits, based on the
detection of refs/replace.
Make it so that additionally the use of --no-replace-objects is
detected: I.e. replaced commits are only decorated as replaced when they
are actually replaced.
Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
---
Sorry for being late to the party. Trying to keep up.
---
log-tree.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/log-tree.c b/log-tree.c
index 74fc20d..f65f6b6 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -96,6 +96,8 @@ static int add_ref_decoration(const char *refname, const unsigned char *sha1, in
enum decoration_type type = DECORATION_NONE;
if (!prefixcmp(refname, "refs/replace/")) {
+ if (!read_replace_refs)
+ return 0;
unsigned char original_sha1[20];
if (get_sha1_hex(refname + 13, original_sha1)) {
warning("invalid replace ref %s", refname);
--
1.7.6.845.gc3c05
^ permalink raw reply related
* Re: [PATCH] log: Do not decorate replacements with --no-replace-objects
From: Michael J Gruber @ 2011-08-25 15:08 UTC (permalink / raw)
To: Nguyen Thai Ngoc Duy; +Cc: git, Junio C Hamano
In-Reply-To: <CACsJy8BOhU7-aTN2TPRRoQ=_mSfbOstXFRfpyoPmrr_Gbqg0pg@mail.gmail.com>
Nguyen Thai Ngoc Duy venit, vidit, dixit 25.08.2011 15:55:
> 2011/8/25 Michael J Gruber <git@drmicha.warpmail.net>:
>> Make it so that additionally the use of --no-replace-objects is
>> detected: I.e. replaced commits are only decorated as replaced when they
>> are actually replaced.
>
> Yeah.. I forgot about this.
>
>> @@ -95,7 +95,7 @@ static int add_ref_decoration(const char *refname, const unsigned char *sha1, in
>> struct object *obj;
>> enum decoration_type type = DECORATION_NONE;
>>
>> - if (!prefixcmp(refname, "refs/replace/")) {
>> + if (read_replace_refs && !prefixcmp(refname, "refs/replace/")) {
>> unsigned char original_sha1[20];
>> if (get_sha1_hex(refname + 13, original_sha1)) {
>> warning("invalid replace ref %s", refname);
>
> You should put "if (!read_replace_refs) return 0;" inside "if
> (!prefixcmp..", otherwise it'll come to the ref decoration code below
> and my second paragraph in 5267d29's commit message will be reverted.
Right, thanks for checking.
> I thought my patch was
> - simple
> - replace is rarely used
> therefore neglected the tests. Perhaps you can also add a few tests
> here. It's not that simple after all.
It would take a bit to do so, but this is a fix to a recently introduced
feature, so it should go along quickly. v2 upcoming.
Michael
^ permalink raw reply
* [PATCH] replace: List replacement along with the object
From: Michael J Gruber @ 2011-08-25 14:39 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Christian Couder
The documentation could be misunderstood as if "git replace -l" lists
the replacements of the specified objects. Currently, it lists the
replaced objects.
Change the output to the form "<object> <replacement>" so that there is
an easy way to find the replacement, besides the more difficult to find
git show-ref $(git replace -l).
Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
---
Noted in passing while testing decorations.
---
Documentation/git-replace.txt | 2 +-
builtin/replace.c | 2 +-
t/t6050-replace.sh | 8 ++++----
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Documentation/git-replace.txt b/Documentation/git-replace.txt
index 17df525..9bf3ff8 100644
--- a/Documentation/git-replace.txt
+++ b/Documentation/git-replace.txt
@@ -58,7 +58,7 @@ OPTIONS
-l <pattern>::
List replace refs for objects that match the given pattern (or
- all if no pattern is given).
+ all if no pattern is given) in the form "<object> <replacement>".
Typing "git replace" without arguments, also lists all replace
refs.
diff --git a/builtin/replace.c b/builtin/replace.c
index fe3a647..f8c5a9f 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -26,7 +26,7 @@ static int show_reference(const char *refname, const unsigned char *sha1,
const char *pattern = cb_data;
if (!fnmatch(pattern, refname, 0))
- printf("%s\n", refname);
+ printf("%s %s\n", refname, sha1_to_hex(sha1));
return 0;
}
diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh
index 5c87f28..665b308 100755
--- a/t/t6050-replace.sh
+++ b/t/t6050-replace.sh
@@ -119,10 +119,10 @@ test_expect_success 'repack, clone and fetch work' '
'
test_expect_success '"git replace" listing and deleting' '
- test "$HASH2" = "$(git replace -l)" &&
- test "$HASH2" = "$(git replace)" &&
+ test "$HASH2 $R" = "$(git replace -l)" &&
+ test "$HASH2 $R" = "$(git replace)" &&
aa=${HASH2%??????????????????????????????????????} &&
- test "$HASH2" = "$(git replace -l "$aa*")" &&
+ test "$HASH2 $R" = "$(git replace -l "$aa*")" &&
test_must_fail git replace -d $R &&
test_must_fail git replace -d &&
test_must_fail git replace -l -d $HASH2 &&
@@ -137,7 +137,7 @@ test_expect_success '"git replace" replacing' '
test_must_fail git replace $HASH2 $R &&
git replace -f $HASH2 $R &&
test_must_fail git replace -f &&
- test "$HASH2" = "$(git replace)"
+ test "$HASH2 $R" = "$(git replace)"
'
# This creates a side branch where the bug in H2
--
1.7.6.845.gc3c05
^ permalink raw reply related
* Re: [PATCH] log: Do not decorate replacements with --no-replace-objects
From: Nguyen Thai Ngoc Duy @ 2011-08-25 13:55 UTC (permalink / raw)
To: Michael J Gruber; +Cc: git, Junio C Hamano
In-Reply-To: <ad41e81daa6f9fc4654ae4c312f293202519a5d0.1314279822.git.git@drmicha.warpmail.net>
2011/8/25 Michael J Gruber <git@drmicha.warpmail.net>:
> Make it so that additionally the use of --no-replace-objects is
> detected: I.e. replaced commits are only decorated as replaced when they
> are actually replaced.
Yeah.. I forgot about this.
> @@ -95,7 +95,7 @@ static int add_ref_decoration(const char *refname, const unsigned char *sha1, in
> struct object *obj;
> enum decoration_type type = DECORATION_NONE;
>
> - if (!prefixcmp(refname, "refs/replace/")) {
> + if (read_replace_refs && !prefixcmp(refname, "refs/replace/")) {
> unsigned char original_sha1[20];
> if (get_sha1_hex(refname + 13, original_sha1)) {
> warning("invalid replace ref %s", refname);
You should put "if (!read_replace_refs) return 0;" inside "if
(!prefixcmp..", otherwise it'll come to the ref decoration code below
and my second paragraph in 5267d29's commit message will be reverted.
I thought my patch was
- simple
- replace is rarely used
therefore neglected the tests. Perhaps you can also add a few tests
here. It's not that simple after all.
--
Duy
^ permalink raw reply
* [PATCH] log: Do not decorate replacements with --no-replace-objects
From: Michael J Gruber @ 2011-08-25 13:44 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy, Junio C Hamano
5267d29 (log: decorate "replaced" on to replaced commits, 2011-08-19)
introduced textual decorations for replaced commits, based on the
detection of refs/replace.
Make it so that additionally the use of --no-replace-objects is
detected: I.e. replaced commits are only decorated as replaced when they
are actually replaced.
Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
---
Sorry for being late to the party. Trying to keep up.
---
log-tree.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/log-tree.c b/log-tree.c
index 74fc20d..2066bb7 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -95,7 +95,7 @@ static int add_ref_decoration(const char *refname, const unsigned char *sha1, in
struct object *obj;
enum decoration_type type = DECORATION_NONE;
- if (!prefixcmp(refname, "refs/replace/")) {
+ if (read_replace_refs && !prefixcmp(refname, "refs/replace/")) {
unsigned char original_sha1[20];
if (get_sha1_hex(refname + 13, original_sha1)) {
warning("invalid replace ref %s", refname);
--
1.7.6.845.gc3c05
^ permalink raw reply related
* Re: [PATCH v3] gitk: Allow commit editing
From: Michal Sojka @ 2011-08-25 13:15 UTC (permalink / raw)
To: Jeff King; +Cc: git, paulus
In-Reply-To: <20110825031420.GB3465@sigill.intra.peff.net>
On Thu, 25 Aug 2011, Jeff King wrote:
> On Fri, Aug 19, 2011 at 02:25:53PM +0200, Michal Sojka wrote:
>
> > + if {[exec git branch -r --contains=$rowmenuid] ne {}} {
> > + if {![confirm_popup [mc "The commit you are going to edit appears in at least one\
> > + remote branch. It is a bad idea to change a branch that is\
> > + possibly used by other people. See git-rebase(1) for details.\n\n\
> > + Do you want to continue?"]]} return }
>
> We frown on using porcelain like "git branch" here, because it was not
> meant to be scriptable (i.e., its behavior may change in future
> releases).
>
> As I mentioned elsewhere, I think you really want to see whether the
> commit is referenced by any other ref, not just branches; if it is, then
> the rebase is potentially problematic. You can do that with something
> like:
>
> us=`git symbolic-ref HEAD`
> git for-each-ref --format='%(refname)' |
> while read ref; do
> test "$ref" = $us" && continue
> echo "^$ref"
> done |
> git rev-list HEAD --stdin
>
> That will give a list of commits found only on HEAD and nowhere else
> (i.e., those which are safe to rebase). If your commit is among them,
> then it's safe.
I implemented something like you ontlined above (see below). Instead of
rev-listing HEAD, I use the commit id to be edited. This way I don't
have to find the commit in the returned list, but I only check whether
the list is empty or not.
Additionally, besides skiping HEAD ref, I also skip refs/stash. Rebasing
before stash should not (I hope) cause any problems and therefore it is
not necessary to warn the user.
> Speaking of which, notice that I used HEAD here. What happens with your
> patch if I do:
>
> $ git checkout foo
> $ gitk bar
>
> and select a commit to edit that is not in "foo"?
I added a check for this. If this is detected, error message is
displayed and no edit is possible.
The other changes in this version are:
- added --no-autosquash to rebase invocation
- fixed indexes of menu entries following the new edit entry.
Regards,
-Michal
--8<---------------cut here---------------start------------->8---
I often use gitk to review patches before pushing them out and I would
like to have an easy way to edit commits. The current approach with
copying the commitid, switching to terminal, invoking git rebase -i,
editing the commit and switching back to gitk is a way too complicated
just for changing a single letter in the commit message or removing a
debug printf().
This patch adds "Edit this commit" item to gitk's context menu which
invokes interactive rebase in a non-interactive way :-). git gui is
used to actually edit the commit.
Besides editing the commit message, splitting of commits, as described
in git-rebase(1), is also supported.
The user is warned if the commit to be edited is contained in another
ref besides the current branch and the stash (e.g. in a remote
branch). Additionally, error box is displayed if the user attempts to
edit a commit not contained in the current branch.
Signed-off-by: Michal Sojka <sojka@os.inf.tu-dresden.de>
---
gitk-git/gitk | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 67 insertions(+), 4 deletions(-)
diff --git a/gitk-git/gitk b/gitk-git/gitk
index 4cde0c4..0968efa 100755
--- a/gitk-git/gitk
+++ b/gitk-git/gitk
@@ -2487,6 +2487,7 @@ proc makewindow {} {
makemenu $rowctxmenu {
{mc "Diff this -> selected" command {diffvssel 0}}
{mc "Diff selected -> this" command {diffvssel 1}}
+ {mc "Edit this commit" command edit_commit}
{mc "Make patch" command mkpatch}
{mc "Create tag" command mktag}
{mc "Write commit to file" command writecommit}
@@ -8428,18 +8429,18 @@ proc rowmenu {x y id} {
if {$id ne $nullid && $id ne $nullid2} {
set menu $rowctxmenu
if {$mainhead ne {}} {
- $menu entryconfigure 7 -label [mc "Reset %s branch to here" $mainhead] -state normal
+ $menu entryconfigure 8 -label [mc "Reset %s branch to here" $mainhead] -state normal
} else {
- $menu entryconfigure 7 -label [mc "Detached head: can't reset" $mainhead] -state disabled
+ $menu entryconfigure 8 -label [mc "Detached head: can't reset" $mainhead] -state disabled
}
if {[info exists markedid] && $markedid ne $id} {
- $menu entryconfigure 9 -state normal
$menu entryconfigure 10 -state normal
$menu entryconfigure 11 -state normal
+ $menu entryconfigure 12 -state normal
} else {
- $menu entryconfigure 9 -state disabled
$menu entryconfigure 10 -state disabled
$menu entryconfigure 11 -state disabled
+ $menu entryconfigure 12 -state disabled
}
} else {
set menu $fakerowmenu
@@ -9102,6 +9103,68 @@ proc cherrypick {} {
notbusy cherrypick
}
+proc rebase_ok {id} {
+ if {[exec git merge-base $id HEAD] ne $id} {
+ error_popup [mc "You cannot edit commits outside of the current branch."]
+ return 0
+ }
+ set headref [exec git symbolic-ref HEAD]
+ set allrefs [split [exec git for-each-ref --format=%(refname)] "\n"]
+ set otherrefs {}
+ set otherrefsneg ""
+ foreach ref $allrefs {
+ if {$ref eq "refs/stash" || $ref eq $headref} continue
+ set otherrefsneg "$otherrefsneg^$ref\n"
+ }
+
+ # Check whether some other refs contain the commit to be edited
+ if {[exec git rev-list --stdin $id << $otherrefsneg] eq {}} {
+ if { [confirm_popup [mc "The commit you are going to edit is contained in another, possibly non-local, ref (e.g. branch or tag).\
+ It is a bad idea to change a ref that is possibly used by other people. See git-rebase(1) for details.\n\n\
+ Do you want to continue?"]]} {
+ return 1
+ } else {
+ return 0
+ }
+ }
+ return 1
+}
+
+proc edit_commit {} {
+ global rowmenuid selectedline
+
+ if {![rebase_ok $rowmenuid]} return
+
+ nowbusy edit [mc "Editing commit"]
+ if {[catch {exec sh -c "(GIT_EDITOR='sed -ie 1s/^pick/edit/' git rebase -p -i --no-autosquash $rowmenuid^ && git gui citool --amend) 2>&1"} err]} {
+ notbusy edit
+ error_popup $err
+ exec git rebase --abort
+ return
+ }
+ set newcommit [exec git rev-parse HEAD]
+ while {[catch {exec sh -c "git diff-index --quiet --cached HEAD && git diff-files --quiet"} err]} {
+ if {[confirm_popup [mc "There are uncommited changes in the working tree or in the index.\
+ Do you want to create a new commit (OK) or discard them (Cancel)?"]]} {
+ catch {exec git gui citool} err;
+ # In case of error (i.e. the user did not commit anything), we just ask him again
+ } else {
+ exec git reset --hard
+ }
+ }
+ if {[catch {exec sh -c "git rebase --continue 2>&1"} err]} {
+ notbusy edit
+ error_popup $err
+ exec git rebase --abort
+ return
+ }
+ updatecommits
+ # XXX How to select the edited commit? This doesn't work.
+ selbyid $newcommit
+ notbusy edit
+}
+
+
proc resethead {} {
global mainhead rowmenuid confirm_ok resettype NS
--
1.7.5.4
--8<---------------cut here---------------end--------------->8---
^ permalink raw reply related
* Re: [PATCH] rebase -i: clean error message for --continue after failed exec
From: Johannes Sixt @ 2011-08-25 13:04 UTC (permalink / raw)
To: Matthieu Moy; +Cc: Junio C Hamano, git
In-Reply-To: <vpqzkiydl21.fsf@bauges.imag.fr>
Am 25.08.2011 09:09, schrieb Matthieu Moy:
> Junio C Hamano<gitster@pobox.com> writes:
>> I wonder if doing something like this would be more direct approach to
>> achieve the same thing.
>
> Not the same thing, but both patches could go well together.
>
> Mine covers
>
> pick deadbeef
> exec make test
> # :-( make test failed, I'm going to fix it
> hack hack hack
> git add changes
> # OK, seems fixed.
> git rebase --continue
> # --> rebase tells me I forgot to commit my fixup patch
This is exactly my use-case that discovered the problem and which I would
like to see fixed, FWIW.
-- Hannes
^ permalink raw reply
* [PATCH v2] submodule: Demonstrate known breakage during recursive merge
From: Brad King @ 2011-08-25 12:28 UTC (permalink / raw)
To: git, gitster; +Cc: Heiko Voigt
In-Reply-To: <680d2679c3275c01152500760311b5f96a93ea62.1314193375.git.brad.king@kitware.com>
Since commit 68d03e4a (Implement automatic fast-forward merge for
submodules, 2010-07-07) we try to suggest submodule commits that resolve
a conflict. Consider a true recursive merge case
b---bc
/ \ /
o X
\ / \
c---cb
in which the two heads themselves (bc,cb) had resolved a submodule
conflict (i.e. reference different commits than their parents). The
submodule merge search runs during the temporary merge of the two merge
bases (b,c) and prints out a suggestion that is not meaningful to the
user. Then during the main merge the submodule merge search runs again
but dies with the message
fatal: --ancestry-path given but there are no bottom commits
while trying to enumerate candidates. Demonstrate this known breakage
with a new test in t7405-submodule-merge covering the case.
Signed-off-by: Brad King <brad.king@kitware.com>
---
This fixes the first version of the patch by using "merge --no-commit"
instead of "merge -n" where the intention is to not commit the merge.
Both instances are followed by a submodule checkout, add, and then a
real commit. Now the history in the test actually looks like what
is in the commit message.
Brad
t/t7405-submodule-merge.sh | 51 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 51 insertions(+), 0 deletions(-)
diff --git a/t/t7405-submodule-merge.sh b/t/t7405-submodule-merge.sh
index a8fb30b..14da2e3 100755
--- a/t/t7405-submodule-merge.sh
+++ b/t/t7405-submodule-merge.sh
@@ -228,4 +228,55 @@ test_expect_success 'merging with a modify/modify conflict between merge bases'
git merge d
'
+# canonical criss-cross history in top and submodule
+test_expect_success 'setup for recursive merge with submodule' '
+ mkdir merge-recursive &&
+ (cd merge-recursive &&
+ git init &&
+ mkdir sub &&
+ (cd sub &&
+ git init &&
+ test_commit a &&
+ git checkout -b sub-b master &&
+ test_commit b &&
+ git checkout -b sub-c master &&
+ test_commit c &&
+ git checkout -b sub-bc sub-b &&
+ git merge sub-c &&
+ git checkout -b sub-cb sub-c &&
+ git merge sub-b &&
+ git checkout master) &&
+ git add sub &&
+ git commit -m a &&
+ git checkout -b top-b master &&
+ (cd sub && git checkout sub-b) &&
+ git add sub &&
+ git commit -m b &&
+ git checkout -b top-c master &&
+ (cd sub && git checkout sub-c) &&
+ git add sub &&
+ git commit -m c &&
+ git checkout -b top-bc top-b &&
+ git merge -s ours --no-commit top-c &&
+ (cd sub && git checkout sub-bc) &&
+ git add sub &&
+ git commit -m bc &&
+ git checkout -b top-cb top-c &&
+ git merge -s ours --no-commit top-b &&
+ (cd sub && git checkout sub-cb) &&
+ git add sub &&
+ git commit -m cb)
+'
+
+# merge should leave submodule unmerged in index
+test_expect_failure 'recursive merge with submodule' '
+ (cd merge-recursive &&
+ test_must_fail git merge top-bc &&
+ echo "160000 $(git rev-parse top-cb:sub) 2 sub" > expect2 &&
+ echo "160000 $(git rev-parse top-bc:sub) 3 sub" > expect3 &&
+ git ls-files -u > actual &&
+ grep "$(cat expect2)" actual > /dev/null &&
+ grep "$(cat expect3)" actual > /dev/null)
+'
+
test_done
--
1.7.4.4
^ permalink raw reply related
* [PATCH] git-notes.txt: clarify -C vs. copy and -F
From: Michael J Gruber @ 2011-08-25 10:26 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Johan Herland
In-Reply-To: <7v1v1pr97x.fsf@alter.siamese.dyndns.org>
The current description of '-C' together with the analogy to 'git commit
-C' can lead to the wrong conclusion that '-C' copies notes between
objects. Make this clearer by rewording and pointing to 'copy'.
The example for attaching binary notes with 'git hash-object' followed
by 'git notes add -C' immediately raises the question: "Why not use 'git
notes add -F'?". Answer it (the latter is not binary-safe).
Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
---
This one has been lying around and fell under the rugs of the discussion
for a ui redesign which never happened. So I think it's still worth it.
---
Documentation/git-notes.txt | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt
index 6a187f2..e8319ea 100644
--- a/Documentation/git-notes.txt
+++ b/Documentation/git-notes.txt
@@ -142,8 +142,9 @@ OPTIONS
-C <object>::
--reuse-message=<object>::
- Take the note message from the given blob object (for
- example, another note).
+ Take the given blob object (for example, another note) as the
+ note message. (Use `git notes copy <object>` instead to
+ copy notes between objects.)
-c <object>::
--reedit-message=<object>::
@@ -285,6 +286,8 @@ $ blob=$(git hash-object -w a.out)
$ git notes --ref=built add -C "$blob" HEAD
------------
+(You cannot simply use `git notes --ref=built add -F a.out HEAD`
+because that is not binary-safe.)
Of course, it doesn't make much sense to display non-text-format notes
with 'git log', so if you use such notes, you'll probably need to write
some special-purpose tools to do something useful with them.
--
1.7.6.845.gc3c05
^ 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