Bug: "orphaned" trees indistinguishable in git log --graph output
Hi, I noticed a problem how git log --graph represents orphaned trees, i.e. how it renders a forest (and not just a single tree). If a repository is comprised of multiple unconnected trees it can easily happen that their commits are intertwined in the output of git log --graph so that the root of one tree seems to be (re)based on a commit of the other tree and there is no indication that they are indeed separate. This first example shows the problem in the first indention level: mkdir git-log-decorate-forest1 cd git-log-decorate-forest1 git init git commit --allow-empty -m"Tree 1 - branch 1 - commit 1" git branch tree1_branch1 git checkout --orphan tree2_branch1 git commit --allow-empty -m"Tree 2 - branch 1 - commit 1" git log --decorate --graph --oneline --all The log call at the end leads to something like this: * 73c925a (tree1_branch1, master) Tree 1 - branch 1 - commit 1 * e22a694 (HEAD -> tree2_branch1) Tree 2 - branch 1 - commit 1 Note the asterisks in the beginning that usually indicates that the commit sits "on top" of the previous one (in contrast to "|" used for distinct branches). There is no way to tell from the output that the two commits reside on different trees. The second example shows that the problem also happens at deeper indention levels if multiple branches are involved. NB: the sleep is important due to git log's sorting (I did not try to understand the details though). mkdir git-log-decorate-forest2 cd git-log-decorate-forest2 git init git commit --allow-empty -m"Tree 1 - branch 1 - commit 1" git commit --allow-empty -m"Tree 1 - branch 1 - commit 2" git branch tree1_branch1 git checkout --orphan tree2_branch1 git commit --allow-empty -m"Tree 2 - branch 1 - commit 1" git checkout master git reset --hard tree1_branch1^ git commit --allow-empty -m"Tree 1 - branch 2 - commit 2" git branch tree1_branch2 git checkout tree2_branch1 sleep 1 git commit --amend --no-edit --allow-empty git checkout master git commit --allow-empty -m"Tree 1 - branch 2 - commit 3" git log --decorate --graph --oneline --all The git log output looks something like this: * ae86680 (HEAD -> master) Tree 1 - branch 2 - commit 3 * 844c8c3 (tree1_branch2) Tree 1 - branch 2 - commit 2 | * 8e6ed1e (tree2_branch1) Tree 2 - branch 1 - commit 1 | * 3fc176d (tree1_branch1) Tree 1 - branch 1 - commit 2 |/ * 88b8313 Tree 1 - branch 1 - commit 1 Note how 8e6ed1e looks as if it sits on top of 3fc176d? But it doesn't. It's an orphaned commit and thus part of a completely separated tree! In gitk one has to enable the display of all branches but then the two trees are distinguishable. gitg works fine (for once) as well. The output of git-cola's DAG viewer is even worse than git log's output: there (the commit of) the second tree is embedded in the master branch between tree1_branch2 and the initial commit of tree 1 (88b8313)! Here are the (outdated) versions of the tools tested: git version 2.11.0 gitg 3.23.0 cola version 2.10 If the test cases above no longer work I can try to reproduce the problem with git's HEAD if need be. I really hope I have not overlooked any related bug reports or even a fix... the issue is a bit hard to search for ;) As a fix I guess it would make sense to have additional indention for the distinct trees... just like how branches are indented but of course without the |/ split below. -- Kind regards/Mit freundlichen Grüßen, Stefan Tauner
Re: Un-paged commit messages in git filter-branch's commit-filter?
On Mon, 1 Aug 2016 19:24:29 -0400 Jeff King wrote: > So could it be that your lines actually _are_ broken in the git objects, > but "%s" and other tools try to salvage them as a single subject? YES! :) Thanks so much! I was apparently ignoring this trivial explanation because I was too much persuaded that the actual commits had missing line breaks and only something in git was adding them. But it is actually the other way around as you said: the few commands that print the overlong lines are those that rely on %s. gitg for example parses the output of the following: git show --num-stat --pretty="format:%s%n%n%b%n\x01" I was not aware that %s lumps lines together if it does not find a proper subject on the first line. I can work with that now. Thanks again! -- Kind regards/Mit freundlichen Grüßen, Stefan Tauner -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Un-paged commit messages in git filter-branch's commit-filter?
On Mon, 1 Aug 2016 17:36:31 -0400 Jeff King wrote: > On Sun, Jul 31, 2016 at 06:39:35PM +0200, Stefan Tauner wrote: > > > > There are some output formats that will wrap lines, but by default, > > > filter-branch should not be using them (and I could not reproduce the > > > issue in a simple test). Can you show us what your commit-filter looks > > > like? > > > > Thanks for your answer. I have tried to reproduce it in other (newly > > created) repositories but failed. However, it seems to relate to some > > kind of persistent paging setting, is that possible? > > git config -l does not show anything suspicious. > > > > The following commands produce paged output: > > git show hash > > git show --pretty=%B > > git log hash^..hash > > Commit message in gitk > > > > > > These do NOT produce paged output: > > git patch hash^..hash > > Commit message in gitg 0.2.7 > > What is "git patch"? An alias for "format-patch?". Yes, sorry. And this is the most amazing thing about this behavior... what's so different between format-patch and log or show --pretty=%B. Shouldn't these match 100%? > > > This is the script I tried to use to reproduce the problem: > > > > #!/bin/bash > > export LC_ALL=C > > input=$(cat) > > echo "=== > > $input > > ===" >> /tmp/paging_bug.txt > > git commit-tree "$@" -m "$input" > > Can you be more specific about the input you're feeding to git and the > output you're seeing? > > For instance, if I do: > > git init > echo content >file > git add file > git commit -m "$(perl -e 'print join(" ", 1..100)')" > > I get a commit message with one long unwrapped line, which I can view > via git-log, etc. That's approximately what I did in my tests as well. And like you, when I do this in a fresh repository, it works like that.. > Now if I try to run filter-branch on that: > > git filter-branch --commit-filter ' > input=$(cat) > { > echo "" > echo $input > echo "" > } >>/tmp/paging_bug.txt > git commit-tree "$@" -m "$input" > ' > > then the commit remains unchanged, and paging_bug shows one long line. as well as filter-branch. That's what I meant when I wrote I cannot reproduce it with a new repository (to create a MWE). I wrote the first mail under the presumption that filter-branch is somehow involved but apparently it is not the only git command and receives the mangled input already as the commands stated in the last email show. > What am I missing? > > (I wondered at first if the extra "cat" and "-m" could be messing up > whitespace for you, but it should not, as the quoting around "$input" > should preserve things like newlines. And anyway, the bug in that case > would be the _opposite_; I'd expect it to stuff everything onto a single > line rather than breaking lines). The commit messages I try to process are nothing special really... just very long and not subject-like (because SVN and not giving too much thought to them sometimes). The only special thing I can think of is that they have been processed by git-svn earlier. -- Kind regards/Mit freundlichen Grüßen, Stefan Tauner -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Un-paged commit messages in git filter-branch's commit-filter?
On Thu, 16 Jun 2016 05:59:47 -0400 Jeff King wrote: > On Mon, Jun 13, 2016 at 08:28:18AM +0200, Stefan Tauner wrote: > > > I am trying to do a major cleanup of the repository in one of my > > projects (and switch from git-svn to native git). I have developed a > > commit-filter script over the last months that massages partially > > dreadful commit messages into something acceptable. While I am not 100% > > sure I think that upgrading git has broken it partially. AFAICT since > > the update the commit-filter does not get the original message anymore > > but at least the subject/first paragraph is run through a pager or > > something similar: > > The first line is broken into multiple lines (i.e. some line breaks are > > inserted about every 72 characters where none have been before). > > There are some output formats that will wrap lines, but by default, > filter-branch should not be using them (and I could not reproduce the > issue in a simple test). Can you show us what your commit-filter looks > like? Thanks for your answer. I have tried to reproduce it in other (newly created) repositories but failed. However, it seems to relate to some kind of persistent paging setting, is that possible? git config -l does not show anything suspicious. The following commands produce paged output: git show hash git show --pretty=%B git log hash^..hash Commit message in gitk These do NOT produce paged output: git patch hash^..hash Commit message in gitg 0.2.7 This is the script I tried to use to reproduce the problem: #!/bin/bash export LC_ALL=C input=$(cat) echo "=== $input ===" >> /tmp/paging_bug.txt git commit-tree "$@" -m "$input" -- Kind regards/Mit freundlichen Grüßen, Stefan Tauner -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Un-paged commit messages in git filter-branch's commit-filter?
Hello, I am trying to do a major cleanup of the repository in one of my projects (and switch from git-svn to native git). I have developed a commit-filter script over the last months that massages partially dreadful commit messages into something acceptable. While I am not 100% sure I think that upgrading git has broken it partially. AFAICT since the update the commit-filter does not get the original message anymore but at least the subject/first paragraph is run through a pager or something similar: The first line is broken into multiple lines (i.e. some line breaks are inserted about every 72 characters where none have been before). I have tried to run "git --no-pager filter-branch ..." to no avail. I have briefly looked at the source but could not find any proofs... Any hints would be appreciated. This is how I run my script: tmpvar="$(http://vger.kernel.org/majordomo-info.html
Re: pre-push hook does not get input on non-fast-forward pushes
On Mon, 28 Mar 2016 14:44:20 -0700 Junio C Hamano wrote: > Stefan Tauner writes: > > The pre-push hook is not the only thing that may prevent you from > pushing a ref update. As you noticed, non-fast-forward check may > trigger and decide that a ref is not going to be pushed, and that > may happen before we call the pre-push hook. > > Information about what is to be pushed is provided on the hook's > standard input with lines of the form ... > > So when the pre-push is called, the refs that will not fast-forward > may not be among the "what is to be pushed", hence not reported. > > We _could_ add something like this to the documentation, but we do > not necessarily want to promise that the order of checks to stay > "internal checks like non-ff check first before pre-push hook", so > this update may not be an improvement. The current text conveys > enough information without making such a promise, but you need to > read it carefully. I understand but that behavior is quite surprising and the wording not that clear (if one is not aware of the behavior already) IMHO. If the fast forward check is done beforehand and no refs remain, why is the script called at all? Or put otherwise, why isn't git aborting before that? That would seem way more logical... consistency is a good argument to call the hook with no refs anyway... but the abort/filter order is remarkable and should be documented in some way IMHO. > > Documentation/githooks.txt | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt > index 9ef2469..605ba4d 100644 > --- a/Documentation/githooks.txt > +++ b/Documentation/githooks.txt > @@ -201,7 +201,9 @@ does not yet exist the `` will be 40 `0`. > If a ref is to be > deleted, the `` will be supplied as `(delete)` and the ` SHA-1>` will be 40 `0`. If the local commit was specified by something other > than a name which could be expanded (such as `HEAD~`, or a SHA-1) it will be > -supplied as it was originally given. > +supplied as it was originally given. A request to update remote ref that has > +already been rejected for other reasons (e.g. failing to pass a fast-forward > +test) does not appear in the input. > > If this hook exits with a non-zero status, 'git push' will abort without > pushing anything. Information about why the push is rejected may be sent LGTM... if you don't want to promise anything then maybe something like "may not appear" instead of "does not appear" is better. As long as the reason for no input is stated more explicitly than currently I am happy. -- Kind regards/Mit freundlichen Grüßen, Stefan Tauner -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
pre-push hook does not get input on non-fast-forward pushes
Hi, I noticed that without an additional --force the pre-push hook does not get any input on stdin if a push would result in non-fast-forward uploads. This is not a problem per se (although I don't get the rationale) but it is undocumented and the latter left me puzzled. (Please keep me in CC since I am not subscribed, thanks) -- Kind regards/Mit freundlichen Grüßen, Stefan Tauner -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html