* [Bug] git pull doesn't recognize --work-tree parameter
From: Kirill Likhodedov @ 2011-10-13 8:38 UTC (permalink / raw)
To: git
'git pull' doesn't work from outside the working tree even if '--work-tree' is specified:
# git version
git version 1.7.6
# git --git-dir=/Users/loki/sandbox/git/child/.git --work-tree=/Users/loki/sandbox/git/child pull
fatal: /opt/local/libexec/git-core/git-pull cannot be used without a working tree.
Note that 'git fetch' and 'git merge origin/master' work fine, so 'git pull' should be easy to fix :)
# git --git-dir=/Users/loki/sandbox/git/child/.git --work-tree=/Users/loki/sandbox/git/child merge origin/master
Already up-to-date.
----------------------------------
Kirill Likhodedov
JetBrains, Inc
http://www.jetbrains.com
"Develop with pleasure!"
^ permalink raw reply
* [BUG] git checkout <branch> allowed with uncommitted changes
From: arQon @ 2011-10-13 8:40 UTC (permalink / raw)
To: git
Which, as you'd expect, results in both the on-disk copies and other branches
becoming corrupted.
Tested on git versions 1.7.6 and 1.7.7 (msysgit)
http://benno.id.au/blog/2011/10/01/git-recursive-merge-broken describes
something that sounds similar, but that's supposedly fixed on 1.7.7,
whereas this happens on that as well.
master is a tracking branch, "ttfcon" is the branch I was using to develop
a change. Got to a good point on the branch, merged it in:
$ git co master
$ git merge ttfcon
Updating b9f0c75..6280b7a
Fast-forward
.gitignore | 2 ++
code/renderer/tr_font.cpp | 27 ++++++++-------------------
2 files changed, 10 insertions(+), 19 deletions(-)
$ git st
# On branch master
# Your branch is ahead of 'origin/master' by 3 commits.
back to the branch to mess around with a couple of things to be sure this
is what i want to push
$ git co ttfcon
do stuff
$ git st
# On branch ttfcon
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: code/freetype-2.3.11/builds/win32/visualc/freetype.vcproj
# modified: code/renderer/tr_font.cpp
so far so good...
$ git ci -m "blah" code/freetype-2.3.11/builds/win32/visualc/freetype.vcproj
1 files changed, 4 insertions(+), 0 deletions(-)
note that tr_font is locally modified and still *not committed* at this point.
$ git co master
M code/renderer/tr_font.cpp
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 3 commits.
boom. instead of rejecting the branch change, git switches branches anyway,
and doesn't do anything about the uncommitted changes in the file itself -
meaning they're now effectively "in" master because they're still on disk,
so now the master is poisoned.
"git st" does show the change:
# On branch master
# Changes not staged for commit:
# modified: code/renderer/tr_font.cpp
but it's a change I never MADE on this branch (ie master), only on the
other branch.
"git diff" is just as confused as I am:
$ git diff ttfcon
--- a/code/renderer/tr_font.cpp
+++ b/code/renderer/tr_font.cpp
+ // git branch bug
So it's picking up the difference between the two branches, but as far as
the *actual file* goes, master now has a line in it that shouldn't be there.
I'm just trying out git as a possible replacement for SVN, so maybe I'm
mistaken about what "should" happen, but AIUI git switching branches with
uncommitted changes is a bug (and given that it poisoned a branch that I
wasn't on, it certainly looks like one). A couple of days ago it DID complain
when I tried to switch with uncommitted files still present, so it was working
properly then. I have no idea what's made it happy to ignore them now:
nothing's changed that I know of.
At this point, reverting the master with "checkout --" also wipes out the
changes on the other branch. It's like the merge symlinked the two branches
rather than, well, merging them.
If this is user error, and merge is supposed to break the tree like that,
then sorry for wasting your time, but I can't find anything in the docs that
says (or even suggests) that it should, so...
Thanks.
^ permalink raw reply
* Re: [PATCH 2/9] completion: optimize refs completion
From: SZEDER Gábor @ 2011-10-13 10:40 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Shawn O. Pearce, Jonathan Nieder
In-Reply-To: <7v7h497m01.fsf@alter.siamese.dyndns.org>
On Wed, Oct 12, 2011 at 05:50:38PM -0700, Junio C Hamano wrote:
> SZEDER Gábor <szeder@ira.uka.de> writes:
>
> > After a unique command or option is completed, in most cases it is a
> > good thing to add a trailing a space, but sometimes it doesn't makes
>
> s/makes/make/;
>
> > __gitcomp() therefore iterates over all possible completion words it
> > got as argument, and checks each word whether a trailing space is
> > necessary or not. This is ok for commands, options, etc., i.e. when
> > the number of words is relatively small, but can be noticeably slow
> > for large number of refs. However, while options might or might not
> > need that trailing space, refs are always handled uniformly and always
> > get that trailing space (or a trailing '.' for 'git config
> > branch.<head>.').
> > ...
> > So, add a specialized variant of __gitcomp() that only deals with
> > possible completion words separated by a newline and uniformly appends
> > the trailing space to all words using 'compgen -S' (or any other
> > suffix, if specified), so no iteration over all words is done.
>
> s/is done./is needed./;
>
> I think I followed your logic (very well written ;-)
Thanks; learned it around here ;)
> but feel somewhat
> dirty, as you are conflating the "These things are separated with newlines"
> with "These things do not need inspection --- they all need suffix", which
> has one obvious drawback --- you may find other class of words that always
> want a SP after each of them but the source that generates such a class of
> words may not separate the list elements with a newline.
Yes, there are a couple of other places where SP is uniformly needed,
for example completion of subcommands for bisect, notes, stash, etc.,
merge strategies, whitespace options, which are all separated by SP,
or help topics, which are separated by SP, TAB, and NL. However, it
really is necessary that no SP is used to separate those words, see
below, so we can't use this optimization in these cases. And since
the number of possible completion words in these cases is usually low,
it doesn't worth the effort to restructure those words to not use SP
separator, because it doesn't really make a performance difference
anyway.
> Because a ref cannot have $IFS whitespace in its name anyway, I think you
> can rename __gitcomp_nl to a name that conveys more clearly what it does
> (i.e. "complete and always append suffix"), drop the IFS fiddling from the
> function, and get the same optimization, no?
Unfortunately, this optimization depends on the IFS fiddling, because
we want to append a SP. The same IFS trick is done in __gitcomp(),
too. If we use the default IFS containing an SP and append a SP to
possible completion words by 'compgen -S " "' (or by word="$word ", as
in __gitcomp_1()), then that SP will be promply stripped off when
compgen's output is stored in the COMPREPLY array. Using an IFS
without SP keeps those SP suffixes. Perhaps I should've mentioned
this explicitly in the commit message, but didn't do so because one of
the referenced commit messages (72e5e989 (bash: Add space after unique
command name is completed., 2007-02-04)) already mentioned it briefly.
But when we use an IFS without SP, that also implies that we can't
pass words separated by SP to __gitcomp_nl(), because those words
won't be split at SPs anymore. Since refs & co. are separated by NL,
it was the obvious choice for this special-purpose IFS. So this
optimization can't work with the class of words mentioned above.
So I thought that it's important to stress that this function can only
deal with NL separated words, hence I named it __gitcomp_nl(). But I
see your point about naming it after what it actually does, so I'm
fine with __gitcomp_add_suffix() or whatever else that indicates
"complete and always append suffix".
Will resend in a day or two, to leave some time for other suggestions.
Best,
Gábor
^ permalink raw reply
* Re: [BUG] git checkout <branch> allowed with uncommitted changes
From: Nguyen Thai Ngoc Duy @ 2011-10-13 10:48 UTC (permalink / raw)
To: arQon; +Cc: git
In-Reply-To: <loom.20111013T094053-111@post.gmane.org>
On Thu, Oct 13, 2011 at 7:40 PM, arQon <arqon@gmx.com> wrote:
> $ git co master
> M code/renderer/tr_font.cpp
> Switched to branch 'master'
> Your branch is ahead of 'origin/master' by 3 commits.
...
> At this point, reverting the master with "checkout --" also wipes out the
> changes on the other branch. It's like the merge symlinked the two branches
> rather than, well, merging them.
It does show you that there are changes in the working tree and you
could have switched back with "git co -", done whatever you want with
your changes then switched to master again.
> A couple of days ago it DID complain
> when I tried to switch with uncommitted files still present, so it was working
> properly then. I have no idea what's made it happy to ignore them now:
> nothing's changed that I know of.
git tries to keep all changes on working tree you have. If you have
changes in file A and the new branch changes in file B, fine. If the
new branch also changes in file A too, it'll complain because
otherwise it may overwrite your changes. What it actual does is "Two
way merge", there is a table in "git read-tree" man page that
describes exactly how it is done, what cases would fail...
I see it as more choices. As I said above, it does tell you there are
changes and you could do something. You could make alias "co" that
check for worktree/index cleanliness before calling checkout.
Something like this maybe (I have not tested it)
git config alias.co '!git update-index --refresh && git diff-files
--quiet && git diff-index --cached --quiet HEAD && git checkout "$@"'
A config key to enforce this may be nice. I don't know, I have never
had problems with current behavior.
--
Duy
^ permalink raw reply
* Re: Git attributes ignored for root directory
From: Gioele Barabucci @ 2011-10-13 10:49 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Michael Haggerty, git
In-Reply-To: <7vfwix7qk2.fsf@alter.siamese.dyndns.org>
On 13/10/2011 00:12, Junio C Hamano wrote:
> Suppose you have a directory "foo" and want to say "I want to ignore
> everything in that directory". You would say "foo/" in .gitignore in the
> higher level and you are happy.
>
> How would you say the same thing if the directory to be ignored weren't
> "foo" but at the top-level of the working tree? There is no such level
> higher than the top-level where you can say "<the name of your project>/"
> in its .gitignore file.
Shouldn't `/.` or `/./` work?
I see that `/*/` in `.gitignores` successfully ignores all the
non-hidden directories in the root project directory. Another accidental
success? :)
--
Gioele Barabucci <gioele@svario.it>
^ permalink raw reply
* Re: [Bug] git pull doesn't recognize --work-tree parameter
From: Nguyen Thai Ngoc Duy @ 2011-10-13 10:55 UTC (permalink / raw)
To: Kirill Likhodedov; +Cc: git
In-Reply-To: <E95C75ED-99F2-463C-A1AB-0F8152696739@jetbrains.com>
On Thu, Oct 13, 2011 at 7:38 PM, Kirill Likhodedov
<kirill.likhodedov@jetbrains.com> wrote:
>
> 'git pull' doesn't work from outside the working tree even if '--work-tree' is specified:
>
> # git version
> git version 1.7.6
> # git --git-dir=/Users/loki/sandbox/git/child/.git --work-tree=/Users/loki/sandbox/git/child pull
> fatal: /opt/local/libexec/git-core/git-pull cannot be used without a working tree.
>
> Note that 'git fetch' and 'git merge origin/master' work fine, so 'git pull' should be easy to fix :)
Not exactly. git-pull is a shell script and may have problems that a
builtin command like git-fetch never has. An "easy" way is to just
build git-pull in. I have such a (stalled) WIP since May. Thanks for
reminding me to finish my work :)
--
Duy
^ permalink raw reply
* Re: [BUG] git checkout <branch> allowed with uncommitted changes
From: Alexey Shumkin @ 2011-10-13 10:59 UTC (permalink / raw)
To: Nguyen Thai Ngoc Duy; +Cc: arQon, git
In-Reply-To: <CACsJy8Dzy5-kOZAjwdx=ooUdnN0L2F3EiNQ7b==3AGQZYjEUXQ@mail.gmail.com>
> On Thu, Oct 13, 2011 at 7:40 PM, arQon <arqon@gmx.com> wrote:
> > $ git co master
> > M code/renderer/tr_font.cpp
> > Switched to branch 'master'
> > Your branch is ahead of 'origin/master' by 3 commits.
>
> ...
>
> > At this point, reverting the master with "checkout --" also wipes
> > out the changes on the other branch. It's like the merge symlinked
> > the two branches rather than, well, merging them.
>
> It does show you that there are changes in the working tree and you
> could have switched back with "git co -", done whatever you want with
> your changes then switched to master again.
>
> > A couple of days ago it DID complain
> > when I tried to switch with uncommitted files still present, so it
> > was working properly then. I have no idea what's made it happy to
> > ignore them now: nothing's changed that I know of.
>
> git tries to keep all changes on working tree you have. If you have
> changes in file A and the new branch changes in file B, fine. If the
> new branch also changes in file A too, it'll complain because
> otherwise it may overwrite your changes. What it actual does is "Two
> way merge", there is a table in "git read-tree" man page that
> describes exactly how it is done, what cases would fail...
>
> I see it as more choices. As I said above, it does tell you there are
> changes and you could do something. You could make alias "co" that
> check for worktree/index cleanliness before calling checkout.
> Something like this maybe (I have not tested it)
>
> git config alias.co '!git update-index --refresh && git diff-files
> --quiet && git diff-index --cached --quiet HEAD && git checkout "$@"'
>
> A config key to enforce this may be nice. I don't know, I have never
> had problems with current behavior.
I agree with the explanation and I like current behavior, as well.
2arQon:
Your expectations is based on SVN experience but as ex-SVN-user, too, I
can (and I want to) say: Git is more flexible and powerful tool then SVN
is. Take is power and change your expectations, and your life will
become better )))
^ permalink raw reply
* Re: [BUG] git checkout <branch> allowed with uncommitted changes
From: arQon @ 2011-10-13 11:51 UTC (permalink / raw)
To: git
In-Reply-To: <20111013145924.2113c142@ashu.dyn.rarus.ru>
Snipping the bug and focusing on one of the after-effects of the bug is,
unfortunately, not helpful to me unless I'm missing your point (which is
certainly possible).
git switched branches while there were uncommitted files. It's not supposed to
do this, ever, unless given -f or -m, and it broke the tree as a result. Even
*with* -f or -m, the behavior I described is incorrect.
The git docs seem to agree with me, which is why there's git stash. If the docs
are wrong, fine, though it seems pretty strange to have a change on BranchA
appear by magic "in" BranchB without any merging.
What I'm after is an understanding / explanation of how something that isn't
supposed to happen, does. I don't care if it's "Because I'm an idiot", "Because
git is broken", or even "Make sure your config has 'git.makebranchesworkproperly
= true' in it, the default is false". If there is no explanation for why git
switches branches when there are still uncommitted files, and there doesn't seem
to be, then it's a pretty catastrophic bug and fixing it would be a Good Thing.
*AFAICT*, committing *a* file is what triggers it.
If you commit -a, which is what all the commits prior to this were, it works
properly. You change branches, and the files on the disk become what they should
be.
If you commit nothing, you correctly get the "uncommitted files" error.
If you do a partial commit though, your tree breaks.
Like I say, if the man page, quote:
"If you have local modifications to one or more files that are different between
the current branch and the branch to which you are switching, the command
refuses to switch branches in order to preserve your modifications in context."
is wrong, and this behavior is deliberate, that's fine. Bizarre, but fine in
the sense that git is doing what it's supposed to (regardless of how
counterintuitive and destructive it is).
If the man page is right though, this is a bug. Maybe it's only in msysgit,
but this is the second time it's happened, so hopefully it's fairly easy to
reproduce.
^ permalink raw reply
* git rebase +
From: Adam Piatyszek @ 2011-10-13 11:48 UTC (permalink / raw)
To: git
Hi,
In the middle of "git rebase --continue" process I hit Ctrl+C today to break
this operation. When I tried to replay the same command it errors out with the
following problem:
ediap@stsrdt1:src/toolfiles: git rebase --continue
Rebasing (2/3)
[Ctrl+C was hit here]
ediap@stsrdt1:src/toolfiles: git rebase --continue
/project/dfttools/libexec/git-core/git-rebase--interactive: line 650:
/home/ediap/project.git/.git/rebase-merge/author-script: No such file or
directory
Is this an expected behavior?
Thanks,
/Adam
^ permalink raw reply
* Re: [BUG] git checkout <branch> allowed with uncommitted changes
From: Andreas Ericsson @ 2011-10-13 12:22 UTC (permalink / raw)
To: arQon; +Cc: git
In-Reply-To: <loom.20111013T130924-792@post.gmane.org>
On 10/13/2011 01:51 PM, arQon wrote:
> Snipping the bug and focusing on one of the after-effects of the bug is,
> unfortunately, not helpful to me unless I'm missing your point (which is
> certainly possible).
>
> git switched branches while there were uncommitted files. It's not supposed to
> do this, ever, unless given -f or -m, and it broke the tree as a result. Even
> *with* -f or -m, the behavior I described is incorrect.
> The git docs seem to agree with me, which is why there's git stash. If the docs
> are wrong, fine, though it seems pretty strange to have a change on BranchA
> appear by magic "in" BranchB without any merging.
>
> What I'm after is an understanding / explanation of how something that isn't
> supposed to happen, does. I don't care if it's "Because I'm an idiot", "Because
> git is broken", or even "Make sure your config has 'git.makebranchesworkproperly
> = true' in it, the default is false". If there is no explanation for why git
> switches branches when there are still uncommitted files, and there doesn't seem
> to be, then it's a pretty catastrophic bug and fixing it would be a Good Thing.
>
> *AFAICT*, committing *a* file is what triggers it.
> If you commit -a, which is what all the commits prior to this were, it works
> properly. You change branches, and the files on the disk become what they should
> be.
> If you commit nothing, you correctly get the "uncommitted files" error.
> If you do a partial commit though, your tree breaks.
>
> Like I say, if the man page, quote:
> "If you have local modifications to one or more files that are different between
> the current branch and the branch to which you are switching, the command
> refuses to switch branches in order to preserve your modifications in context."
This means that if fileX on branchA is different from fileX on branchB and you
*also* have local modifications to fileX, git will refuse to switch branches.
If, on the other hand branchA:fileX == branchB:fileX and you have modifications
to fileX in your work tree, there's no reason to refuse the branch change.
Partly because nothing will be lost and partly because you can just switch
branches back if you decide you've switched branches before committing things
to the first branch.
> is wrong, and this behavior is deliberate, that's fine. Bizarre, but fine in
> the sense that git is doing what it's supposed to (regardless of how
> counterintuitive and destructive it is).
> If the man page is right though, this is a bug. Maybe it's only in msysgit,
> but this is the second time it's happened, so hopefully it's fairly easy to
> reproduce.
>
It's not a bug. You just read the manpage a bit wrong.
Consider this scenario:
$dev works on featureA on branchA, modifying fileX, fileZ and fileY and then
does a commit of fileZ and fileY, but realizes that the changes in fileX
will be good for developing featureB as well, so he changes to a separate
branch to do the update to fileX and be able to merge those changes to
both branchA and branchB.
I've done this myself on numerous occasions when re-working small project-
local API's, and it's very, very handy indeed. If git would refuse me to
change branches without first committing everything I'd have to first
commit the change separately, switch branch, cherrypick the change, go
back to the first branch and remove the commit I made there, merge the
other branch where the commit really belonged and only then I could go
on about my business. If, on the other hand, I happen to switch branches
before committing fileZ in the above example, I can just switch back and
amend my last commit on the first branch.
So yes, this is a feature, and it's a handy one.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
Considering the successes of the wars on alcohol, poverty, drugs and
terror, I think we should give some serious thought to declaring war
on peace.
^ permalink raw reply
* Re: [PATCH 07/14] is_refname_available(): remove the "quiet" argument
From: Drew Northup @ 2011-10-13 12:41 UTC (permalink / raw)
To: mhagger
Cc: Junio C Hamano, git, Jeff King, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips
In-Reply-To: <1318492715-5931-8-git-send-email-mhagger@alum.mit.edu>
On Thu, 2011-10-13 at 09:58 +0200, mhagger@alum.mit.edu wrote:
> From: Michael Haggerty <mhagger@alum.mit.edu>
>
> quiet was always set to 0, so get rid of it. Add a function docstring
> for good measure.
I would like to know if perhaps it was an unfinished project somewhere
to propagate the "quiet" option down to this level before removing the
function argument. Comments?
> +/*
> + * Return true iff a reference named refname could be created without
Did you really mean "iff" (as in "if and only if") or just plain "if"
here?
> + * conflicting with the name of an existing reference. If oldrefname
> + * is non-NULL, ignore potential conflicts with oldrefname (e.g.,
> + * because oldrefname is scheduled for deletion in the same
> + * operation).
> + */
> static int is_refname_available(const char *refname, const char *oldrefname,
> - struct ref_array *array, int quiet)
> + struct ref_array *array)
> {
> int i, namlen = strlen(refname); /* e.g. 'foo/bar' */
> for (i = 0; i < array->nr; i++ ) {
> @@ -1062,9 +1069,8 @@ static int is_refname_available(const char *refname, const char *oldrefname,
> const char *lead = (namlen < len) ? entry->name : refname;
> if (!strncmp(refname, entry->name, cmplen) &&
> lead[cmplen] == '/') {
> - if (!quiet)
> - error("'%s' exists; cannot create '%s'",
> - entry->name, refname);
> + error("'%s' exists; cannot create '%s'",
> + entry->name, refname);
> return 0;
> }
> }
> @@ -1117,7 +1123,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
> * name is a proper prefix of our refname.
> */
> if (missing &&
> - !is_refname_available(refname, NULL, get_packed_refs(NULL), 0)) {
> + !is_refname_available(refname, NULL, get_packed_refs(NULL))) {
> last_errno = ENOTDIR;
> goto error_return;
> }
> @@ -1272,10 +1278,10 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
> if (!symref)
> return error("refname %s not found", oldrefname);
>
> - if (!is_refname_available(newrefname, oldrefname, get_packed_refs(NULL), 0))
> + if (!is_refname_available(newrefname, oldrefname, get_packed_refs(NULL)))
> return 1;
>
> - if (!is_refname_available(newrefname, oldrefname, get_loose_refs(NULL), 0))
> + if (!is_refname_available(newrefname, oldrefname, get_loose_refs(NULL)))
> return 1;
>
> lock = lock_ref_sha1_basic(renamed_ref, NULL, 0, NULL);
--
-Drew Northup
________________________________________________
"As opposed to vegetable or mineral error?"
-John Pescatore, SANS NewsBites Vol. 12 Num. 59
^ permalink raw reply
* Re: [BUG] git checkout <branch> allowed with uncommitted changes
From: arQon @ 2011-10-13 12:42 UTC (permalink / raw)
To: git
In-Reply-To: <loom.20111013T130924-792@post.gmane.org>
Simple testcase:
>git init
Initialized empty Git repository in C:/git-test/.git/
>notepad file1
>notepad file2
>git st
# On branch master
# Initial commit
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
# file1.txt
# file2.txt
nothing added to commit but untracked files present (use "git add" to track)
>git add .
>git st
# On branch master
# Initial commit
# Changes to be committed:
# new file: file1.txt
# new file: file2.txt
>git commit -am "init"
2 files changed, 2 insertions(+), 0 deletions(-)
create mode 100644 file1.txt
create mode 100644 file2.txt
>git co -b foo
Switched to a new branch 'foo'
>notepad file1
(edit stuff)
>git st
# On branch foo
# Changes not staged for commit:
# modified: file1.txt
>git co master
M file1.txt
file1 now has the wrong data in it for "master" branch.
If I go back to "foo" branch and commit the file before doing anything else,
it recovers, and changing branches works correctly again.
--
"If you have local modifications to one or more files that are different
between the current branch and the branch to which you are switching, the
command refuses to switch branches in order to preserve your modifications
in context."
Maybe I'm just missing something obvious, but at the time that last "git
co master" was issued:
The file is locally modified.
The file is different on the current branch (foo) than on the branch to which
I am switching (master).
The command fails to refuse to switch branches.
So I guess the problem is that since the file wasn't re-added after the edit,
git is ignoring it when trying to see if it's safe to branch or not?
^ permalink raw reply
* [PATCH 1/2] submodule: Demonstrate known breakage during recursive merge
From: Brad King @ 2011-10-13 12:59 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Heiko Voigt
In-Reply-To: <cover.1318509069.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>
---
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.5.4
^ permalink raw reply related
* [PATCH 0/2] Do not search submodules in deep recursive merge
From: Brad King @ 2011-10-13 12:59 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Heiko Voigt
In-Reply-To: <7vipnu9hbj.fsf@alter.siamese.dyndns.org>
On 10/12/2011 2:48 PM, Junio C Hamano wrote:
> [Stalled]
>
> * hv/submodule-merge-search (2011-08-26) 5 commits
> - submodule: Search for merges only at end of recursive merge
> - allow multiple calls to submodule merge search for the same path
> - submodule: Demonstrate known breakage during recursive merge
> - push: Don't push a repository with unpushed submodules
> - push: teach --recurse-submodules the on-demand option
> (this branch is tangled with fg/submodule-auto-push.)
AFAICT these two topics are tangled due revision traversal interactions.
I've untangled the two "submodule:" commits from this stalled topic and
rebased on master (34c4461a) resolving one conflict.
The first commit demonstrates a bug: submodule merge search occurs
multiple times for the same path during a recursive merge and fails the
second time. The second commit fixes it by performing the merge search
only at depth 0 recursion. These changes are independent from the
actual merge search and revision traversal logic.
Brad
Brad King (2):
submodule: Demonstrate known breakage during recursive merge
submodule: Search for merges only at end of recursive merge
merge-recursive.c | 6 +++-
submodule.c | 6 ++++-
submodule.h | 2 +-
t/t7405-submodule-merge.sh | 51 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 61 insertions(+), 4 deletions(-)
--
1.7.5.4
^ permalink raw reply
* [PATCH 2/2] submodule: Search for merges only at end of recursive merge
From: Brad King @ 2011-10-13 12:59 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Heiko Voigt
In-Reply-To: <cover.1318509069.git.brad.king@kitware.com>
The submodule merge search is not useful during virtual merges because
the results cannot be used automatically. Furthermore any suggestions
made by the search may apply to commits different than HEAD:sub and
MERGE_HEAD:sub, thus confusing the user. Skip searching for submodule
merges during a virtual merge such as that between B and C while merging
the heads of:
B---BC
/ \ /
A X
\ / \
C---CB
Run the search only when the recursion level is zero (!o->call_depth).
This fixes known breakage tested in t7405-submodule-merge.
Signed-off-by: Brad King <brad.king@kitware.com>
---
merge-recursive.c | 6 ++++--
submodule.c | 6 +++++-
submodule.h | 2 +-
t/t7405-submodule-merge.sh | 2 +-
4 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/merge-recursive.c b/merge-recursive.c
index c34a4f1..cc664c3 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -946,8 +946,10 @@ static struct merge_file_info merge_file_1(struct merge_options *o,
free(result_buf.ptr);
result.clean = (merge_status == 0);
} else if (S_ISGITLINK(a->mode)) {
- result.clean = merge_submodule(result.sha, one->path, one->sha1,
- a->sha1, b->sha1);
+ result.clean = merge_submodule(result.sha,
+ one->path, one->sha1,
+ a->sha1, b->sha1,
+ !o->call_depth);
} else if (S_ISLNK(a->mode)) {
hashcpy(result.sha, a->sha1);
diff --git a/submodule.c b/submodule.c
index 0b709bc..0fd10a0 100644
--- a/submodule.c
+++ b/submodule.c
@@ -794,7 +794,7 @@ static void print_commit(struct commit *commit)
int merge_submodule(unsigned char result[20], const char *path,
const unsigned char base[20], const unsigned char a[20],
- const unsigned char b[20])
+ const unsigned char b[20], int search)
{
struct commit *commit_base, *commit_a, *commit_b;
int parent_count;
@@ -849,6 +849,10 @@ int merge_submodule(unsigned char result[20], const char *path,
* user needs to confirm the resolution.
*/
+ /* Skip the search if makes no sense to the calling context. */
+ if (!search)
+ return 0;
+
/* find commit which merges them */
parent_count = find_first_merges(&merges, path, commit_a, commit_b);
switch (parent_count) {
diff --git a/submodule.h b/submodule.h
index 799c22d..80e04f3 100644
--- a/submodule.h
+++ b/submodule.h
@@ -28,7 +28,7 @@ int fetch_populated_submodules(int num_options, const char **options,
int quiet);
unsigned is_submodule_modified(const char *path, int ignore_untracked);
int merge_submodule(unsigned char result[20], const char *path, const unsigned char base[20],
- const unsigned char a[20], const unsigned char b[20]);
+ const unsigned char a[20], const unsigned char b[20], int search);
int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remotes_name);
#endif
diff --git a/t/t7405-submodule-merge.sh b/t/t7405-submodule-merge.sh
index 14da2e3..0d5b42a 100755
--- a/t/t7405-submodule-merge.sh
+++ b/t/t7405-submodule-merge.sh
@@ -269,7 +269,7 @@ test_expect_success 'setup for recursive merge with submodule' '
'
# merge should leave submodule unmerged in index
-test_expect_failure 'recursive merge with submodule' '
+test_expect_success '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 &&
--
1.7.5.4
^ permalink raw reply related
* Re: [BUG] git checkout <branch> allowed with uncommitted changes
From: arQon @ 2011-10-13 13:09 UTC (permalink / raw)
To: git
In-Reply-To: <4E96D819.20905@op5.se>
Andreas Ericsson <ae <at> op5.se> writes:
[snip]
> This means that if fileX on branchA is different from fileX on branchB and you
> *also* have local modifications to fileX, git will refuse to switch branches.
> If, on the other hand branchA:fileX == branchB:fileX and you have modifications
> to fileX in your work tree, there's no reason to refuse the branch change.
There's an EXCELLENT reason to refuse the branch change: once it happens, what
git is then telling is branchA, is not.
> It's not a bug. You just read the manpage a bit wrong.
[snip]
> So yes, this is a feature, and it's a handy one.
Thanks for the explanation. Unfortunately, I still can't see it as anything but
a critical bug. Consider this:
You're working on branchA and you have a bunch of uncommitted changes.
You can't remember some detail of the bug you're fixing, so you switch branches
to the master. You have to rebuild that branch, because your last build was from
your branch. git now builds the master with sources that were NEVER committed
to it. How is that not a total failure to maintain branch integrity?
If that's the way git is, then that's how it is; and if there isn't a setting
that can make it actually preserve branches properly, then there isn't. Which
sucks for me, because an SCCS that lies about what branch you're "really" on
is worse than useless, so I'm stuck with SVN. :(
Thanks again for clearing it up for me though.
^ permalink raw reply
* Re: [BUG] git checkout <branch> allowed with uncommitted changes
From: Holger Hellmuth @ 2011-10-13 12:55 UTC (permalink / raw)
To: arQon; +Cc: git
In-Reply-To: <loom.20111013T141239-151@post.gmane.org>
On 13.10.2011 14:42, arQon wrote:
>> git co -b foo
> Switched to a new branch 'foo'
>> notepad file1
> (edit stuff)
>> git st
> # On branch foo
> # Changes not staged for commit:
> # modified: file1.txt
>
>> git co master
> M file1.txt
>
> Maybe I'm just missing something obvious, but at the time that last "git
> co master" was issued:
>
> The file is locally modified.
> The file is different on the current branch (foo) than on the branch to which
> I am switching (master).
Wrong. On branch foo as well as on master the same old file1.txt is
committed. You never staged nor committed the new file1.txt anywhere.
> The command fails to refuse to switch branches.
^ permalink raw reply
* Re: Git attributes ignored for root directory
From: Johannes Sixt @ 2011-10-13 13:16 UTC (permalink / raw)
To: Gioele Barabucci; +Cc: Junio C Hamano, Michael Haggerty, git
In-Reply-To: <4E96C220.5050601@svario.it>
Am 10/13/2011 12:49, schrieb Gioele Barabucci:
> I see that `/*/` in `.gitignores` successfully ignores all the non-hidden
> directories in the root project directory. Another accidental success? :)
No, that's by design. The first slash means "apply only in this directory,
not any subdirectories", and the slash at the end means "match only if the
name is a directory".
-- Hannes
^ permalink raw reply
* Re: git rebase +
From: Johannes Sixt @ 2011-10-13 13:21 UTC (permalink / raw)
To: Adam Piatyszek; +Cc: git
In-Reply-To: <loom.20111013T134405-495@post.gmane.org>
Am 10/13/2011 13:48, schrieb Adam Piatyszek:
> In the middle of "git rebase --continue" process I hit Ctrl+C today to break
> this operation. When I tried to replay the same command it errors out with the
> following problem:
> /project/dfttools/libexec/git-core/git-rebase--interactive: line 650:
> /home/ediap/project.git/.git/rebase-merge/author-script: No such file or
> directory
>
> Is this an expected behavior?
Hitting Ctrl-C during git-rebase results undefined behavior. git-rebase is
a shell script and was never designed to operate in any form of atomicity.
You should have let it run until it stopped. Then you could have said 'git
rebase --abort' (if it didn't complete) or 'git reset --hard ORIG_HEAD'
(if it completed).
-- Hannes
^ permalink raw reply
* [PATCH 1/4] git-gui: search and linenumber input are mutual exclusive in the blame view
From: Bert Wesarg @ 2011-10-13 13:48 UTC (permalink / raw)
To: Pat Thoyts; +Cc: David Fries, git, Bert Wesarg
It was possible to open the search input (Ctrl+S) and the goto-line input
(Ctrl+G) at the same time. Prevent this.
Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
---
lib/blame.tcl | 22 ++++++++++++++++------
1 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/lib/blame.tcl b/lib/blame.tcl
index 2099776..691941e 100644
--- a/lib/blame.tcl
+++ b/lib/blame.tcl
@@ -280,11 +280,11 @@ constructor new {i_commit i_path i_jump} {
$w.ctxm add command \
-label [mc "Find Text..."] \
-accelerator F7 \
- -command [list searchbar::show $finder]
+ -command [cb _show_finder]
$w.ctxm add command \
-label [mc "Goto Line..."] \
-accelerator "Ctrl-G" \
- -command [list linebar::show $gotoline]
+ -command [cb _show_linebar]
menu $w.ctxm.enc
build_encoding_menu $w.ctxm.enc [cb _setencoding]
$w.ctxm add cascade \
@@ -351,13 +351,13 @@ constructor new {i_commit i_path i_jump} {
bind $w_cviewer <Tab> "[list focus $w_file];break"
bind $w_cviewer <Button-1> [list focus $w_cviewer]
bind $w_file <Visibility> [cb _focus_search $w_file]
- bind $top <F7> [list searchbar::show $finder]
- bind $top <Key-slash> [list searchbar::show $finder]
- bind $top <Control-Key-s> [list searchbar::show $finder]
+ bind $top <F7> [cb _show_finder]
+ bind $top <Key-slash> [cb _show_finder]
+ bind $top <Control-Key-s> [cb _show_finder]
bind $top <Escape> [list searchbar::hide $finder]
bind $top <F3> [list searchbar::find_next $finder]
bind $top <Shift-F3> [list searchbar::find_prev $finder]
- bind $top <Control-Key-g> [list linebar::show $gotoline]
+ bind $top <Control-Key-g> [cb _show_linebar]
catch { bind $top <Shift-Key-XF86_Switch_VT_3> [list searchbar::find_prev $finder] }
grid configure $w.header -sticky ew
@@ -1349,4 +1349,14 @@ method _resize {new_height} {
set old_height $new_height
}
+method _show_finder {} {
+ linebar::hide $gotoline
+ searchbar::show $finder
+}
+
+method _show_linebar {} {
+ searchbar::hide $finder
+ linebar::show $gotoline
+}
+
}
--
1.7.6.789.gb4599
^ permalink raw reply related
* [PATCH 3/4] git-gui: only except numbers in the goto-line input
From: Bert Wesarg @ 2011-10-13 13:48 UTC (permalink / raw)
To: Pat Thoyts; +Cc: David Fries, git, Bert Wesarg
In-Reply-To: <1d1c91fdaa0bfd31067fd2e06f3f1ecf5597b8d3.1318513492.git.bert.wesarg@googlemail.com>
Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
---
lib/line.tcl | 16 ++++++++++++++--
1 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/lib/line.tcl b/lib/line.tcl
index 692485a..70785e1 100644
--- a/lib/line.tcl
+++ b/lib/line.tcl
@@ -15,7 +15,11 @@ constructor new {i_w i_text args} {
${NS}::frame $w
${NS}::label $w.l -text [mc "Goto Line:"]
- entry $w.ent -textvariable ${__this}::linenum -background lightgreen
+ entry $w.ent \
+ -textvariable ${__this}::linenum \
+ -background lightgreen \
+ -validate key \
+ -validatecommand [cb _validate %P]
${NS}::button $w.bn -text [mc Go] -command [cb _incrgoto]
pack $w.l -side left
@@ -26,7 +30,7 @@ constructor new {i_w i_text args} {
grid remove $w
bind $w.ent <Return> [cb _incrgoto]
- bind $w.ent <Escape> [list linebar::hide $this]
+ bind $w.ent <Escape> [cb hide]
bind $w <Destroy> [list delete_this $this]
return $this
@@ -55,6 +59,14 @@ method editor {} {
return $w.ent
}
+method _validate {P} {
+ # only accept numbers as input
+ if {[regexp {\d*} $P]} {
+ return 1
+ }
+ return 0
+}
+
method _incrgoto {} {
if {$linenum ne {}} {
$ctext see $linenum.0
--
1.7.6.789.gb4599
^ permalink raw reply related
* [PATCH 2/4] git-gui: clear the goto line input when hiding
From: Bert Wesarg @ 2011-10-13 13:48 UTC (permalink / raw)
To: Pat Thoyts; +Cc: David Fries, git, Bert Wesarg
In-Reply-To: <1d1c91fdaa0bfd31067fd2e06f3f1ecf5597b8d3.1318513492.git.bert.wesarg@googlemail.com>
Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
---
lib/line.tcl | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/lib/line.tcl b/lib/line.tcl
index 4913bdd..692485a 100644
--- a/lib/line.tcl
+++ b/lib/line.tcl
@@ -41,6 +41,7 @@ method show {} {
method hide {} {
if {[visible $this]} {
+ $w.ent delete 0 end
focus $ctext
grid remove $w
}
--
1.7.6.789.gb4599
^ permalink raw reply related
* [RFC/PATCH 4/4] git-gui: incremental goto line in blame view
From: Bert Wesarg @ 2011-10-13 13:48 UTC (permalink / raw)
To: Pat Thoyts; +Cc: David Fries, git, Bert Wesarg
In-Reply-To: <1d1c91fdaa0bfd31067fd2e06f3f1ecf5597b8d3.1318513492.git.bert.wesarg@googlemail.com>
The view jumps now to the given line number after each key press.
Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
---
I didn't know this before, but gedits goto-line-dialog works this way.
lib/line.tcl | 15 +++++++++++----
1 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/lib/line.tcl b/lib/line.tcl
index 70785e1..0113e06 100644
--- a/lib/line.tcl
+++ b/lib/line.tcl
@@ -20,7 +20,7 @@ constructor new {i_w i_text args} {
-background lightgreen \
-validate key \
-validatecommand [cb _validate %P]
- ${NS}::button $w.bn -text [mc Go] -command [cb _incrgoto]
+ ${NS}::button $w.bn -text [mc Go] -command [cb _goto]
pack $w.l -side left
pack $w.bn -side right
@@ -29,7 +29,8 @@ constructor new {i_w i_text args} {
eval grid conf $w -sticky we $args
grid remove $w
- bind $w.ent <Return> [cb _incrgoto]
+ trace add variable linenum write [cb _goto_cb]
+ bind $w.ent <Return> [cb _goto]
bind $w.ent <Escape> [cb hide]
bind $w <Destroy> [list delete_this $this]
@@ -67,10 +68,16 @@ method _validate {P} {
return 0
}
-method _incrgoto {} {
+method _goto_cb {name ix op} {
+ after idle [cb _goto 1]
+}
+
+method _goto {{nohide {0}}} {
if {$linenum ne {}} {
$ctext see $linenum.0
- hide $this
+ if {!$nohide} {
+ hide $this
+ }
}
}
--
1.7.6.789.gb4599
^ permalink raw reply related
* Re: [BUG] git checkout <branch> allowed with uncommitted changes
From: arQon @ 2011-10-13 13:58 UTC (permalink / raw)
To: git
In-Reply-To: <4E96D819.20905@op5.se>
Andreas Ericsson <ae <at> op5.se> writes:
> there's no reason to refuse the branch change.
> Partly because nothing will be lost
Actually, this isn't true either, because of the second bug: doing a revert
in branchA causes the changes in branchB to be lost. This can't possibly be
the intended behavior: again, it completely violates the integrity of branches
by allowing changes on one branch to impact a different branch.
Your interpretation of the manpage doubtless matches the actual behavior of git,
but I find it staggering if that truly is what was intended. It basically means
that if you have local modifications, git will Break Your Entire Tree. That
makes changing while you *do* have local mods more than a little undesirable,
to put it mildly, which is something that a literal reading of the manpage would
suggest is exactly what the "refuse to switch" is for. I guess only Linus knows
what he actually meant. :)
Anyway, I guess it's all moot: call it a feature or call it a bug, this cross-
branch destruction is a deal-breaker for me, especially given the bug above that
actually loses data outright, rather than "only" putting multiple branches into
an incorrect state.
Thanks for your time and help.
^ permalink raw reply
* Re: [BUG] git checkout <branch> allowed with uncommitted changes
From: Carlos Martín Nieto @ 2011-10-13 13:59 UTC (permalink / raw)
To: arQon; +Cc: git
In-Reply-To: <loom.20111013T144822-277@post.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 3195 bytes --]
On Thu, 2011-10-13 at 13:09 +0000, arQon wrote:
> Andreas Ericsson <ae <at> op5.se> writes:
> [snip]
> > This means that if fileX on branchA is different from fileX on branchB and you
> > *also* have local modifications to fileX, git will refuse to switch branches.
> > If, on the other hand branchA:fileX == branchB:fileX and you have modifications
> > to fileX in your work tree, there's no reason to refuse the branch change.
>
> There's an EXCELLENT reason to refuse the branch change: once it happens, what
> git is then telling is branchA, is not.
When you changed branches, git told you that a file had been changed in
the working tree. When you run 'git diff', it tells you the differences
between what you have in your working tree and what's in the branch[0].
Git is trying hard not to loose your modifications (maybe it was a
one-liner, maybe it was three hours of work) to the file.
>
> > It's not a bug. You just read the manpage a bit wrong.
> [snip]
> > So yes, this is a feature, and it's a handy one.
>
> Thanks for the explanation. Unfortunately, I still can't see it as anything but
> a critical bug. Consider this:
>
> You're working on branchA and you have a bunch of uncommitted changes.
> You can't remember some detail of the bug you're fixing, so you switch branches
> to the master. You have to rebuild that branch, because your last build was from
> your branch. git now builds the master with sources that were NEVER committed
> to it. How is that not a total failure to maintain branch integrity?
It sound like you've misunderstood what a branch is for git. A branch is
only ever changed when you commit. What checkout does is change what the
current branch is. For a case like what you describe, the developer
would either do a temporary commit that they'd change later or stash the
changes[1]. You could also use git-new-workdir (from contrib/) so you
have two different directories that share the object storage. That has a
few rough edges, but if you restrict it to a broken branch, you
shouldn't have any problems.
>
> If that's the way git is, then that's how it is; and if there isn't a setting
> that can make it actually preserve branches properly, then there isn't. Which
> sucks for me, because an SCCS that lies about what branch you're "really" on
> is worse than useless, so I'm stuck with SVN. :(
Don't think of it as being "in" a branch. A checkout in git changes the
active branch. If there are any files that are different between the two
branches, they are changed. By switching branches with uncommitted
changes, you're telling git that you would rather use the other branch
to do your changes in. But git isn't doing this silently. After the
checkout, it lists the files that have local modifications, so the
developer can switch branches again and commit or stash the changes.
cmn
[0] Really it's between the working tree and the index, but since you
just switched branches, the index is the same, and using it in that
sentence would just cause confusion.
[1] 'git stash' is a command that saves your uncommitted changes on a
stack so you can recover them later.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ 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