* [PATCH] nice ftplugin for vim, that shows the commited diff in a split'ed buffer.
From: Pierre Habouzit @ 2006-10-17 0:31 UTC (permalink / raw)
To: git; +Cc: Pierre Habouzit
In-Reply-To: <11610450702261-git-send-email-madcoder@debian.org>
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
contrib/vim/README | 6 ++++
contrib/vim/ftplugin/gitcommit.vim | 61 ++++++++++++++++++++++++++++++++++++
2 files changed, 67 insertions(+), 0 deletions(-)
diff --git a/contrib/vim/README b/contrib/vim/README
index 9e7881f..26c1682 100644
--- a/contrib/vim/README
+++ b/contrib/vim/README
@@ -6,3 +6,9 @@ To syntax highlight git's commit message
$ cat >>$HOME/.vimrc <<'EOF'
autocmd BufNewFile,BufRead COMMIT_EDITMSG set filetype=gitcommit
EOF
+
+To use the fancy split-view with the currently commited diff, you need to:
+ 1. Copy ftplugin/gitcommit.vim to vim's ftplugin directory:
+ $ mkdir -p $HOME/.vim/ftplugin
+ $ cp ftplugin/gitcommit.vim $HOME/.vim/ftplugin
+ 2. Auto-detect the editing of git commit files (see above).
diff --git a/contrib/vim/ftplugin/gitcommit.vim b/contrib/vim/ftplugin/gitcommit.vim
new file mode 100644
index 0000000..f9efd59
--- /dev/null
+++ b/contrib/vim/ftplugin/gitcommit.vim
@@ -0,0 +1,61 @@
+if exists("b:did_ftplugin")
+ finish
+endif
+
+let b:did_ftplugin = 1
+
+setlocal tw=74
+setlocal nowarn nowb
+
+"{{{ function Git_diff_windows
+
+function! Git_diff_windows()
+ let i = 0
+ let list_of_files = ''
+
+ " drop everything until '# (will commit)' and the next empty line
+ while i <= line('$')
+ let line = getline(i)
+ if line =~ '^#\s*(will commit)$'
+ let i = i + 2
+ break
+ endif
+
+ let i = i + 1
+ endwhile
+
+ " read file names until we have EOF or an empty line
+ while i <= line('$')
+ let line = getline(i)
+ if line =~ '^#\s*[a-z ]*:.*->.*$'
+ let file = substitute(line, '\v^#[^:]*:.*->\s*(.*)\s*$', '\1', '')
+ let list_of_files = list_of_files . ' '.file
+ let file = substitute(line, '\v^#[^:]*:\s*(.*)\s*->.*$', '\1', '')
+ let list_of_files = list_of_files . ' '.file
+ elseif line =~ '^#\s*[a-z ]*:'
+ let file = substitute(line, '\v^#[^:]*:\s*(.*)\s*$', '\1', '')
+ let list_of_files = list_of_files . ' '.file
+ elseif line =~ '^#\s*$'
+ break
+ endif
+
+ let i = i + 1
+ endwhile
+
+ if list_of_files == ""
+ return
+ endif
+
+ rightbelow vnew
+ silent! setlocal ft=diff previewwindow bufhidden=delete nobackup noswf nobuflisted nowrap buftype=nofile
+ exe 'normal :r!LANG=C cd ..; git diff HEAD -- ' . list_of_files . "\n1Gdd"
+ exe 'normal :r!LANG=C cd ..; git diff HEAD -- ' . list_of_files . " \| git apply --stat\no\<esc>1GddO\<esc>"
+ setlocal nomodifiable
+ redraw!
+ wincmd p
+ redraw!
+endfunction
+
+"}}}
+
+call Git_diff_windows()
--
1.4.2.3
^ permalink raw reply related
* [PATCH] be more vim-ish, and also syntax hilight Signed-off-by lines.
From: Pierre Habouzit @ 2006-10-17 0:31 UTC (permalink / raw)
To: git; +Cc: Pierre Habouzit
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
contrib/vim/syntax/gitcommit.vim | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/contrib/vim/syntax/gitcommit.vim b/contrib/vim/syntax/gitcommit.vim
index a9de09f..d0c6e5d 100644
--- a/contrib/vim/syntax/gitcommit.vim
+++ b/contrib/vim/syntax/gitcommit.vim
@@ -1,3 +1,14 @@
+" Vim syntax file
+" Language: git commit message
+
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
+ finish
+endif
+
+syn region gitSignedOff start=/^Signed-off-by:/ end=/$/ contains=gitAuthor,gitEmail
+syn region gitAuthor contained start=/\s/ end=/$/
+
syn region gitLine start=/^#/ end=/$/
syn region gitCommit start=/^# Updated but not checked in:$/ end=/^#$/ contains=gitHead,gitCommitFile
syn region gitHead contained start=/^# (.*)/ end=/^#$/
@@ -8,6 +19,9 @@ syn match gitCommitFile contained /^#\t.
syn match gitChangedFile contained /^#\t.*/hs=s+2
syn match gitUntrackedFile contained /^#\t.*/hs=s+2
+hi def link gitSignedOff Keyword
+hi def link gitAuthor Normal
+
hi def link gitLine Comment
hi def link gitCommit Comment
hi def link gitChanged Comment
@@ -16,3 +30,7 @@ hi def link gitUntracked Comment
hi def link gitCommitFile Type
hi def link gitChangedFile Constant
hi def link gitUntrackedFile Constant
+
+let b:current_syntax = "git"
+
+" vim: ts=8 sw=2
--
1.4.2.3
^ permalink raw reply related
* Re: VCS comparison table
From: Luben Tuikov @ 2006-10-17 0:29 UTC (permalink / raw)
To: Linus Torvalds, Aaron Bentley; +Cc: Jakub Narebski, bazaar-ng, git
In-Reply-To: <Pine.LNX.4.64.0610161625370.3962@g5.osdl.org>
--- Linus Torvalds <torvalds@osdl.org> wrote:
> Well, in the git world, it's really just one shared repository that has
> separate branch-namespaces, and separate working trees (aka "checkouts").
> So yes, it probably matches what bazaar would call a checkout.
>
> Almost nobody seems to actually use it that way in git - it's mostly more
> efficient to just have five different branches in the same working tree,
> and switch between them. When you switch between branches in git, git only
> rewrites the part of your working tree that actually changed, so switching
> is extremely efficient even with a large repo.
>
> So there is seldom any real need or reason to actually have multiple
> checkouts. But it certainly _works_.
It does work, very well at that.
I have a directory for each separate branch and simply use
cd(1) to change the current working directory to that branch.
So, instead of "git checkout <branch>", I do "cd ../<branch>".
One only needs to watch out when one updates the repository.
If there had been updates in those branches, then one needs
to git-reset the "branch" directory... (you know what I mean)
(For example when I come to work in the morning an sync up
with home from my usb key...)
The script is called:
Usage: git-mkdir-of-branch <original-directory> <branch> <new-directory>
where <branch> is the name of an existing branch in <original-directory>/.git/refs/heads
and uses simple symbolic links and some git plumbing to do the
job. It can be found in my git trees. I never bothered to send
it out to Junio, since it could be considered heretic. ;-)
Luben
^ permalink raw reply
* Re: VCS comparison table
From: Linus Torvalds @ 2006-10-17 0:23 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Jakub Narebski, Aaron Bentley, bazaar-ng, git
In-Reply-To: <Pine.LNX.4.63.0610170157270.14200@wbgn013.biozentrum.uni-wuerzburg.de>
On Tue, 17 Oct 2006, Johannes Schindelin wrote:
> >
> > Unless you have branch(es) with totally different contents, like git.git
> > 'todo' branch.
>
> But I _do_ work with it! I just don't need to "checkout" it! Example:
>
> git -p cat-file -p todo:TODO
Ok, if there ever was an example of a strange git command-line, that was
it.
> (How about making git-cat be a short cuut to "git -p cat-file -p"?)
Well, you can just add
[alias]
cat=-p cat-file -p
to your ~/.gitconfig file, and you're there.
[ For all the non-git people here: the first "-p" is shorthand for
"--paginate", and means that git will automatically start a pager for
the output. The second "-p" is shorthand for "pretty" (there's no
long-format command line switch for it, though), and means that git
cat-file will show the result in a human-readable way, regardless of
whether it's just a text-file, or a git directory ]
So then you can do just
git cat todo:TODO
and you're done.
[ So for the non-git people, what that will actually _do_ is to show the
TODO file in the "todo" branch - regardless of whether it is checked out
or not, and start a pager for you. ]
I actually do this sometimes, but I've never done it for branches (and I
do it seldom enough that I haven't added the alias). I do it for things
like
git cat v2.6.16:Makefile
to see what a file looked like in a certain tagged release.
People sometimes find the git command line confusing, but I have to say,
the thing is _damn_ expressive. I've never seen anybody else do things
like the above that git does really naturally, with not that much
confusion really.
Even that "alias" file is quite readable, although I'd suggest writing out
the switches in full, ie
[alias]
cat=--paginate cat-file -p
instead. That kind of helps explains what the alias does and avoids the
question of why there are two "-p" switches.
Linus
^ permalink raw reply
* Re: VCS comparison table
From: Jakub Narebski @ 2006-10-17 0:24 UTC (permalink / raw)
To: git; +Cc: bazaar-ng
In-Reply-To: <Pine.LNX.4.64.0610161704240.3962@g5.osdl.org>
Linus Torvalds wrote:
>> > So there is seldom any real need or reason to actually have multiple
>> > checkouts. But it certainly _works_.
>>
>> But without .git being either symlink, or .git/.gitdir "symref"-link,
>> you have to remember what to ser GIT_DIR to, or parameter for --git-dir
>> option.
>
> I'd strongly suggest that people who do this should actually do
>
> git clone -l
>
> instead of actually playing games with symlinking .git/ itself or using
> GIT_DIR. It means that the two checkouts get separate branch namespaces,
> but that's really what you'd want most of the time.
Or symlinking .git/objects (and perhaps .git/remotes and .git/branches).
BTW. wouldn't it be rather git clone -l -s? What would happenm on repack,
or on repack -a -d?
But it is true that there is no need to checkout different branches
to different working areas.
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* Re: VCS comparison table
From: Linus Torvalds @ 2006-10-17 0:08 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Aaron Bentley, bazaar-ng, git
In-Reply-To: <200610170155.10536.jnareb@gmail.com>
On Tue, 17 Oct 2006, Jakub Narebski wrote:
> > rewrites the part of your working tree that actually changed, so switching
> > is extremely efficient even with a large repo.
>
> Unless you have branch(es) with totally different contents, like git.git
> 'todo' branch.
Yes. I have to say, that's likely a fairly odd case, and I wouldn't be
surprised if other VCS's don't support that mode of operation at _all_.
The fact that git branches can be independent of each other is very
natural in the git world, but
> > So there is seldom any real need or reason to actually have multiple
> > checkouts. But it certainly _works_.
>
> But without .git being either symlink, or .git/.gitdir "symref"-link,
> you have to remember what to ser GIT_DIR to, or parameter for --git-dir
> option.
I'd strongly suggest that people who do this should actually do
git clone -l
instead of actually playing games with symlinking .git/ itself or using
GIT_DIR. It means that the two checkouts get separate branch namespaces,
but that's really what you'd want most of the time.
You _can_ share the whole branch namespace and do the symlink of .git (or
just set GIT_DIR - but that's pretty inconvenient), and it might end up
being "closer" to what some other VCS would do. But the natural thing to
do with git is to just share some of the objects through local "slaving"
of the repositories, and consider them otherwise entirely independent.
Linus
^ permalink raw reply
* Re: VCS comparison table
From: Johannes Schindelin @ 2006-10-17 0:04 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Linus Torvalds, Aaron Bentley, bazaar-ng, git
In-Reply-To: <200610170155.10536.jnareb@gmail.com>
Hi,
On Tue, 17 Oct 2006, Jakub Narebski wrote:
> Linus Torvalds wrote:
> >>> About "checkouts", i.e. working directories with repository elsewhere:
> >>> you can use GIT_DIR environmental variable or "git --git-dir" option,
> >>> or symlinks, and if Nguyen Thai Ngoc D proposal to have .gitdir/.git
> >>> "symref"-like file to point to repository passes, we can use that.
> >>
> >> It sounds like the .gitdir/.git proposal would give Git "checkouts", by
> >> our meaning of the term.
> >
> > Well, in the git world, it's really just one shared repository that has
> > separate branch-namespaces, and separate working trees (aka "checkouts").
> > So yes, it probably matches what bazaar would call a checkout.
> >
> > Almost nobody seems to actually use it that way in git - it's mostly more
> > efficient to just have five different branches in the same working tree,
> > and switch between them. When you switch between branches in git, git only
> > rewrites the part of your working tree that actually changed, so switching
> > is extremely efficient even with a large repo.
>
> Unless you have branch(es) with totally different contents, like git.git
> 'todo' branch.
But I _do_ work with it! I just don't need to "checkout" it! Example:
git -p cat-file -p todo:TODO
(How about making git-cat be a short cuut to "git -p cat-file -p"?)
> > So there is seldom any real need or reason to actually have multiple
> > checkouts. But it certainly _works_.
>
> But without .git being either symlink, or .git/.gitdir "symref"-link,
> you have to remember what to ser GIT_DIR to, or parameter for --git-dir
> option.
You'd just use alternates for that.
But as Linus mentioned in another email, you mostly can use the _same_
working directory. If you want to work on another branch, which is not all
that different from the current branch (say, you have a bug fix branch on
top of an upstream branch), you just _switch_ to it. Git recognizes those
files which are changed, and updates only these. Therefore, if you have
something like a Makefile system to build the project, you actually save
(compile) time as compared to the multiple-checkout scenario.
I use this system a lot, since I maintain a few bugfixes for a few
projects until the bugfixes are applied upstream. BTW the
multiple-branches-in-one-working-directory workflow was propagated by Jeff
a long time ago, and it really changed my way of working. Thanks, Jeff!
Ciao,
Dscho
^ permalink raw reply
* Re: VCS comparison table
From: Jakub Narebski @ 2006-10-16 23:55 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Aaron Bentley, bazaar-ng, git
In-Reply-To: <Pine.LNX.4.64.0610161625370.3962@g5.osdl.org>
Linus Torvalds wrote:
>>> About "checkouts", i.e. working directories with repository elsewhere:
>>> you can use GIT_DIR environmental variable or "git --git-dir" option,
>>> or symlinks, and if Nguyen Thai Ngoc D proposal to have .gitdir/.git
>>> "symref"-like file to point to repository passes, we can use that.
>>
>> It sounds like the .gitdir/.git proposal would give Git "checkouts", by
>> our meaning of the term.
>
> Well, in the git world, it's really just one shared repository that has
> separate branch-namespaces, and separate working trees (aka "checkouts").
> So yes, it probably matches what bazaar would call a checkout.
>
> Almost nobody seems to actually use it that way in git - it's mostly more
> efficient to just have five different branches in the same working tree,
> and switch between them. When you switch between branches in git, git only
> rewrites the part of your working tree that actually changed, so switching
> is extremely efficient even with a large repo.
Unless you have branch(es) with totally different contents, like git.git
'todo' branch.
> So there is seldom any real need or reason to actually have multiple
> checkouts. But it certainly _works_.
But without .git being either symlink, or .git/.gitdir "symref"-link,
you have to remember what to ser GIT_DIR to, or parameter for --git-dir
option.
I'd like to mention once again that in Git branches and tags have
totally separate namespace than repository namespace.
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: git-diff-tree inordinately (O(M*N)) slow on files with many changes
From: Davide Libenzi @ 2006-10-16 23:52 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Junio C Hamano, git, Jim Meyering
In-Reply-To: <Pine.LNX.4.64.0610161604360.3962@g5.osdl.org>
On Mon, 16 Oct 2006, Linus Torvalds wrote:
> That said, it unnecessarily calculates "BITS_IN_LONG - (b)" to shift with,
> because it really shouldn't matter _which_ high bits you use for hashing,
> so you might as well just use the "next" b bits, and have
>
> #define XDL_ADDBITS(v,b) ((v) + ((v) >> (b)))
> #define XDL_MASKBITS(b) ((1UL << (b)) - 1)
> #define XDL_HASHLONG(v,b) (XDL_ADDBITS((unsigned long)(v), b) & XDL_MASKBITS(b))
Ok, I'm fine with this. And my Opteron agrees too:
real 0m0.283s
user 0m0.267s
sys 0m0.016s
- Davide
^ permalink raw reply
* Re: On blame/pickaxe
From: Luben Tuikov @ 2006-10-16 23:45 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vr6xddm7h.fsf@assigned-by-dhcp.cox.net>
Junio,
Excellent write up. Comments inline:
--- Junio C Hamano <junkio@cox.net> wrote:
> I have something that is tentatively called pickaxe, but that is
> different from "diff -S<pickaxe>". The name will need to
> change, perhaps to git-blame.
>
> It's quite a while since the original algorithm sketch that led
> to the current git-blame was posted here; I suspect that most of
> the people recently joined the list haven't seen it. The idea
> in there still applies, though...
>
> Here is a re-drawn sketch of how the 'pickaxe' edition of the
> algorithm works.
>
> 0. Outline.
>
> We track range of lines from a path in one revision. That's
> what "-L n,m", "path", and "commit" parameters to the command
> are about.
>
> When the program starts, the commit given on the command line is
> suspected to be responsible for all lines in the given range.
> But being a suspect and determined to be the guilty party are
> different things.
>
> The name of the game is "not taking responsibility but passing
> the blame to your parents". In other words, "that's not a new
> problem I introduced -- it was there before my patch was
> applied". You are exonerated for those lines that you can
> successfully pass blame to your parent, making that parent a new
> suspect for the lines. There will remain lines you cannot pass
> blame to anybody else -- you will be determined to be the guilty
> party for them. When nobody can pass any more blame to anybody
> else, the dance stops and we will know who is guilty for every
> line of the input.
Stopping early -- that's good.
> 1. Data structure.
>
> We keep track of who the current suspect for each line is in the
> structure called 'scoreboard'. It is a collection of ranges,
> called 'blame_entry'.
>
> Each blame_entry describes which lines (in the final image) it
> is about, who the current suspect for the range is, if the
> suspect is already known to be guilty, where in the suspected
> commit the lines came from (path and line number).
>
> In the 'blame' implementation, a suspect is represented by a
> commit object with one path hanging to its util field.
> 'pickaxe' edition introduces the concept of 'origin', which is a
> pair of <commit,path>. We currently do not use more than one
> path per commit, but hopefully we will soon.
>
>
> 2. Operation.
>
> First the scoreboard is initialized with a single blame_entry
> that makes the path in the commit on the command line the
> suspect for all lines.
>
> Then, we repeatedly pick one entry from the scoreboard, and give
> a chance to the suspect to exonerate himself, by calling
> pass_blame(). The suspect passes the blame to its parents by
> updating the scoreboard, removing his name from ranges of lines
> he can prove that came from his parent and instead writing that
> suspected parent's name. Inside pass_blame(), just before it
> returns, if the suspect cannot pass blame for some lines to
> anybody else, it becomes guilty for them.
>
> When there is no blame_entry in the scoreboard whose truly
> guilty party is still undetermined, we have fully blamed the
> input, and the loop finishes.
>
>
> 3. Passing the blame.
>
> You (a <commit,path> tuple) are suspected for introducing
> certain lines, and you would want to pass blame to your parent.
> How would you do that?
>
> First, you find if your parent has the same path; if not, you
> find if between your parent and you there was a rename and find
> the original path in the parent. If you are a merge, you do so
> for all your parents. The path in the parent and your path may
> have many common lines, and if the lines you are the suspect are
> the same as the ones in the parent, you can pass the blame,
> because these lines were there before you touched them.
Do you handle the case where a merge had a conflict and
the user changed the code (resolved) and then committed?
In this case some lines will have to be blamed on the
merge commit itself.
> How would you find what's common? We run "diff" (diff -u0).
> Unified context-0 diff would give something like:
>
> @@ -n,m +l,k @@
> -removed
> +added
> ...
>
> In this application, we are not interested in the diff text
> itself at all. In fact, we are interested in what's outside the
> diff. If the above is output from parent to you, what it tells
> us is that lines before your line "l" are the same as lines
> before parent's "n", so if the above is the first hunk, you can
> say your lines 1..(l-1) came from your parent and you are not
> responsible for them. The above hunk also tells us that in your
> path, lines after (l+k) are the same as the lines in parent's
> lines (n+m); we will know how many such same lines there are
> (could be zero) by inspecting the next hunk.
>
> For efficiency reasons, inside pass_blame(), we run just one
> diff between the parent and you, and scan the blame_entry for
> the same <commit,path> in the scoreboard, and check overlap with
> each of them. Suppose we are suspected for these lines:
>
> <---- e ----->
>
> and by looking the diff, we determined the range from one parent
> is like this:
>
> <--p--->
>
> Then we can split the blame_entry into three parts:
>
> <-><--p---><->
>
> You are still suspected for the first and the last part of the
> original entry, but for the mid-part you successfully passed the
> blame to that parent. Depending on how the ranges overlap, this
> may split into two, or parent may take blame for the whole range
> (i.e. no split). This is computed in blame_overlap().
>
> When done with one parent, if you are a merge, you will then try
> to pass the blame on the remaining part that you are still
> suspected for to other parents.
>
> The classic 'blame' algorithm stops here, and the current
> pickaxe does the same; you take responsibility for the
> remainder.
>
>
> 4. Passing more blame.
>
> Instead of taking responsibility for the remainder, there are
> other ways to find other people to pass blame on. That's what
> the "NEEDSWORK" comment in pass_blame() is about.
>
> A typical example is a change that moves one static C function
> from lower part of the file to upper part of the same file,
> because you added a new caller in the middle. The path in your
> parent and the path in you would look like this:
>
> parent you
>
> A static foo() {
> B }
> C A
> D B
> E C
> F D
> G ... call foo();
> static foo() { E
> } F
> I G
> J I
>
> With the common part finding code with diff, you will be able to
> pass blames for lines A B C D E F G I J to your parent. You are
> truly guilty for introducing "... call foo();". The problem
> here is that in addition, you will be blamed for the lines that
> implement "static foo() { ... }" at the beginning of your file.
How about move-and-edit scenario? Wouldn't that make the algorithm
somewhat complicated if we wanted to properly describe (blame)
move-and-edit? Or are you going to detect only simple hunk-moves?
> To blame the implementation of foo() to the parent, we could do
> something like this:
>
> for each blame_entry that you are still suspected for,
> diff those lines (and only those lines) with the parent,
> to see if you find a copy. If there is a copy, you can
> pass the blame to the parent.
>
> This needs to be limited for non-trivial changes only, though.
> For example, one of the typical things you would do is to add one
> "else if" clause to a sequence of already existing "if .. else if
> .." chain, like this:
>
> if (foo) {
> ...
> }
> else if (bar) {
> ...
> + }
> + else if (baz) {
> + ...
> }
>
> You are suspected for these three lines; if the "find copies
> again" is allowed to find any insignificant copy, the first line
> (closing brace) you introduced could easily be blamed to an
> unrelated line anywhere in the parent that match /^\t\}$/. To
> prevent such nonsense from happening, we need to limit such
> "find copies" attempt to say minimum of N lines (and minimum of
> M tokens that consist of non-whitespace, non-punctuation
> letters). Also we probably would not want to find a match in
> the whole parent but only in the part of the parent that is
> removed in the parent-to-you diff.
>
> Another typical example is a code restructuring to move one
> function from a file to another file. The same "find copies"
> principle, and caveat for small and insignificant copies, apply
> to this situation as well. If it is a code movement, the file
> that the function moved from needs to be identified, which can
> be done by running diff-tree between parent and you -- anything
> that was modified or removed is a good candidate to look for
> such copies. Again, we probably need to limit the copy-finding
> source to the part that was removed from the parent in the diff
> to you.
Here I see a lot of _arbitration_ in the form of "choose a good
value for N and a good value for M".
Is it possible that we do away with such "user" arbitration,
and instead find an algorithm that solves every case...? Even
if we have to go back to a simpler "blame".
I'm concerned that with "user" arbitration, there would always
be at least one corner case for which the "setting-on-the-knobs"
would fail.
> After the operation 3 (Passing the blame) runs, if movement of
> lines from another file is detected as in the above sketch, we
> will pass blame to an unrelated path in the parent. Some lines
> are blamed on the file we started tracking in the parent, and
> some other lines are blamed on a different file in the parent.
> This is why 'pickaxe' uses <commit,path> tuple (aka 'origin') to
> represent a suspect.
>
> All of this sounds quite simple and not so difficult to code,
> although rejecting insignificant copies would involve fair
> amount of heuristic tweaking like I needed to do while working
> on the rename detection.
Indeed.
Luben
^ permalink raw reply
* Re: VCS comparison table
From: Johannes Schindelin @ 2006-10-16 23:45 UTC (permalink / raw)
To: Aaron Bentley; +Cc: Jakub Narebski, bazaar-ng, git
In-Reply-To: <45340713.6000707@utoronto.ca>
Hi Aaron,
On Mon, 16 Oct 2006, Aaron Bentley wrote:
> --[PinePGP]--------------------------------------------------[begin]--
> Jakub Narebski wrote:
> >>Does it accurately reflect the current status of git? Is their
> >>assessment of git's rename capability correct?
> >
> >
> > For example simple namespace for git: you can use shortened sha1
> > (even to only 6 characters, although usually 8 are used), you can
> > use tags, you can use ref^m~n syntax.
>
> Bazaar's namespace is "simple" because all branches can be named by a
> URL, and all revisions can be named by a URL + a number.
How should this cope with a distributed project? IOW how does it deal with
"this revision and that revision are exactly the same"?
If I understand you correctly, you are claiming that you are not really
identifying a revision, but a revision _at a certain place with a
place-dependent number_. This conflicts with my understanding of a
revision.
> If that's true of Git, then it certainly has a simple namespace. Using
> eight-digit hex values doesn't sound simple to me, though.
It depends on your usage. If you want to do anything interesting, like
assure that you have the correct version, or assure that two different
person's tags actually tag the same revision, there is no simpler
representation.
> > I'm not sure about "No" in "Supports Repository". Git supports multiple
> > branches in one repository, and what's better supports development using
> > multiple branches, but cannot for example do a diff or a cherry-pick
> > between repositories (well, you can use git-format-patch/git-am to
> > cherry-pick changes between repositories...).
>
> That sounds right. So those branches are persistent, and can be worked
> on independently?
Of course! Persistence (and reliability) are the number one goal of git.
Performance is the next one.
As an example of completely independet branches, look at the "next" and
the "todo" branch of git. They are _completely_ independent, i.e. not even
sharing history, let alone files.
> > Git supports renames in its own way; it doesn't use file ids, nor
> > remember renames (the new "note" header for use e.g. by porcelains
> > didn't pass if I remember correctly). But it does *detect* moving
> > _contents_, and even *copying* _contents_ when requested. And of
> > course it detect renames in merges.
>
> You'll note we referred to that bevhavior on the page. We don't think
> what Git does is the same as supporting renames. AIUI, some Git users
> feel the same way.
Oh, we start another flamewar again?
Honestly, if you want to record renames, why don't you also support (with
a command for each of those purposes) code copying? And refactoring? And
copyright year bumps? _put your favourite here_
If you really, really think about it: it makes much more sense to record
your intention in the commit message. So, instead of recording for _every_
_single_ file in folder1/ that it was moved to folder2/, it is better to
say that you moved folder1/ to folder2/ _because of some special reason_!
Same goes for all other thinkable examples.
If you want to track code, then let the tracker do its work, i.e. let
git-pickaxe figure where your code came from. It is likely being more
precise than any human ever can be.
> > Git doesn't have some "plugin framework", but because it has many
> > "plumbing" commands, it is easy to add new commands, and also new
> > merge strategies, using shell scripts, Perl, Python and of course C.
> > So the answer would be "Somewhat", as git has plugable merge strategies,
> > or even "Yes" at it is easy to add new git command.
>
> It sounds like you're saying it's extensible, not that it supports
> plugins. Plugins have very simple installation requirements. They can
> provide merge strategies, repository types, internet protocols, new
> commands, etc., all seamlessly integrated.
>
> What you're describing actually sounds like the Arch approach to
> extensibility: provide a whole bunch of basic commands and let users
> build an RCS on top of that.
It is more like the Unix way. Let each command do _one_ thing, but let it
do it _perfectly_.
> As the author of two different Arch front-ends, I can say I haven't
> found that approach satisfactory. Invoking multiple commands tends
> re-invoke the same validation routines over and over, killing
> efficiency, and diagnostics tend to be pretty poorly integrated.
Welcome to git! Git's commands are very efficient, and you can even pipe
them efficiently! And now that we have GIT_TRACE, diagnostics are no
concern.
Ciao,
Dscho
^ permalink raw reply
* Re: VCS comparison table
From: Nguyen Thai Ngoc Duy @ 2006-10-16 23:39 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Aaron Bentley, bazaar-ng, git
In-Reply-To: <200610170119.09066.jnareb@gmail.com>
On 10/17/06, Jakub Narebski <jnareb@gmail.com> wrote:
> Aaron Bentley wrote:
> > Jakub Narebski wrote:
> >> About "checkouts", i.e. working directories with repository elsewhere:
> >> you can use GIT_DIR environmental variable or "git --git-dir" option,
> >> or symlinks, and if Nguyen Thai Ngoc D proposal to have .gitdir/.git
> >> "symref"-like file to point to repository passes, we can use that.
> >
> > It sounds like the .gitdir/.git proposal would give Git "checkouts", by
> > our meaning of the term.
>
> Actually it is better to work with clone of repository, perhaps either
> symlinking object database, or by alternates mechanism (with alternates
> repositories would share old history, but gather new independetly
> I think).
I agree. Each Git repository is designed to work with one working
directory. Using .gitdir/.git proposal, you are likely to checkout two
working directories from one repo.
--
Duy
^ permalink raw reply
* Re: VCS comparison table
From: Linus Torvalds @ 2006-10-16 23:35 UTC (permalink / raw)
To: Aaron Bentley; +Cc: Jakub Narebski, bazaar-ng, git
In-Reply-To: <45340713.6000707@utoronto.ca>
On Mon, 16 Oct 2006, Aaron Bentley wrote:
>
> Bazaar's namespace is "simple" because all branches can be named by a
> URL, and all revisions can be named by a URL + a number.
>
> If that's true of Git, then it certainly has a simple namespace. Using
> eight-digit hex values doesn't sound simple to me, though.
Hey, "simple" is in the eye of the beholder. You can always just define
Bazaar's naming convention to be simple.
I pretty much _guarantee_ that a "number" is not a valid way to uniquely
name a revision in a distributed environment, though. I bet the "number"
really only names a revision in one _single_ repository, right?
Which measn that it's actually not a "name" of the revision at all. It's
just a local shorthand that has no meaning, and the exact same revision
will be called something different when in somebody elses repository.
I wouldn't call that "simple". I'd call it "insane".
In contrast, in git, a revision is a revision is a revision. If you give
the SHA1 name, it's well-defined even between different repositories, and
you can tell somebody that "revision XYZ is when the problem started", and
they'll know _exactly_ which revision it is, even if they don't have your
particular repository.
Now _that_ is true simplicity. It does automatically mean that the names
are a bit longer, but in this case, "longer" really _does_ mean "simpler".
If you want a short, human-readable name, you _tag_ it. It takes all of a
hundredth of a second to to or so.
> > I'm not sure about "No" in "Supports Repository". Git supports multiple
> > branches in one repository, and what's better supports development using
> > multiple branches, but cannot for example do a diff or a cherry-pick
> > between repositories (well, you can use git-format-patch/git-am to
> > cherry-pick changes between repositories...).
>
> That sounds right. So those branches are persistent, and can be worked
> on independently?
Yes.
> > About "checkouts", i.e. working directories with repository elsewhere:
> > you can use GIT_DIR environmental variable or "git --git-dir" option,
> > or symlinks, and if Nguyen Thai Ngoc D proposal to have .gitdir/.git
> > "symref"-like file to point to repository passes, we can use that.
>
> It sounds like the .gitdir/.git proposal would give Git "checkouts", by
> our meaning of the term.
Well, in the git world, it's really just one shared repository that has
separate branch-namespaces, and separate working trees (aka "checkouts").
So yes, it probably matches what bazaar would call a checkout.
Almost nobody seems to actually use it that way in git - it's mostly more
efficient to just have five different branches in the same working tree,
and switch between them. When you switch between branches in git, git only
rewrites the part of your working tree that actually changed, so switching
is extremely efficient even with a large repo.
So there is seldom any real need or reason to actually have multiple
checkouts. But it certainly _works_.
> You'll note we referred to that bevhavior on the page. We don't think
> what Git does is the same as supporting renames. AIUI, some Git users
> feel the same way.
The fact is, git supports renames better than just about anybody else. It
just does them technically differently. The fact that it happens to be the
_right_ way, and everybody else is incompetent, is not my fault ;)
Linus
^ permalink raw reply
* Re: git-diff-tree inordinately (O(M*N)) slow on files with many changes
From: Linus Torvalds @ 2006-10-16 23:24 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Davide Libenzi, Jim Meyering
In-Reply-To: <7vy7rfub36.fsf@assigned-by-dhcp.cox.net>
On Mon, 16 Oct 2006, Junio C Hamano wrote:
>
> I agree (although I am not sure about the "do it twice for
> small" bit), and I think Davide agrees with you in his reply:
Sure. Davide's all-macro version is fine. I don't like re-using the same
value twice even in a ALL-CAPS macro, so I'm used to inline functions, but
all the uses of XDL_HASHLONG() are fine with multiple uses of the
arguments.
Somebody should just double-check that all the parentheses ended up being
right ;)
It might be easier to read if you write it as
#define BITS_IN_LONG (CHAR_BIT * sizeof(unsigned long))
#define XDL_HIGHBITS(v,b) ((v) >> (BITS_IN_LONG - (b)))
#define XDL_MASKBITS(b) ((1UL << (b)) - 1)
#define XDL_HASHBITS(v,b) (((v) + XDL_HIGHBITS(v,b)) & XDL_MASKBITS(b))
#define XDL_HASHLONG(v,b) XDL_HASHBITS( (unsigned long)(v) , b )
just to avoid one huge #define.
That said, it unnecessarily calculates "BITS_IN_LONG - (b)" to shift with,
because it really shouldn't matter _which_ high bits you use for hashing,
so you might as well just use the "next" b bits, and have
#define XDL_ADDBITS(v,b) ((v) + ((v) >> (b)))
#define XDL_MASKBITS(b) ((1UL << (b)) - 1)
#define XDL_HASHLONG(v,b) (XDL_ADDBITS((unsigned long)(v), b) & XDL_MASKBITS(b))
which generates better code at least on x86 (and x86-64), because the
shift count stays the same for all shifts and can thus be kept in %ecx.
For example, on x86-64, you get
movq %rdi, %rax # copy 'val'
movl $1, %edx # const 1: start generating (1 << b) - 1
shrq %cl, %rax # val >> b
salq %cl, %rdx # 1 << b
leaq (%rdi,%rax), %rax # val + (val >> b)
subq $1, %rdx # (1 << b) -1
andq %rdx, %rax # final hash
which is short and sweet. And on ppc32 (or ppc64) you get
li 9,1 # const 1: start generating (1 << b) - 1
srw 0,3,4 # val >> b
slw 9,9,4 # 1 << b
add 0,0,3 # val + (val >> b)
addi 9,9,-1 # (1 << b) - 1
and 3,0,9 # final hash
in other words, apart from having two shifts (which you can't really
avoid, although a multiply can do one of them) it's just a very efficient
way to mix together (2*b) bits into a (b)-bit hash.
But taking the high bits from the "unsigned long" doesn't add _that_ much
cost. I just suspect that it's a good way to continue to get different
answers on 32-bit and 64-bit architectures.
Linus
^ permalink raw reply
* Re: VCS comparison table
From: Jakub Narebski @ 2006-10-16 23:19 UTC (permalink / raw)
To: Aaron Bentley; +Cc: bazaar-ng, git
In-Reply-To: <45340713.6000707@utoronto.ca>
Aaron Bentley wrote:
> Jakub Narebski wrote:
> >>Does it accurately reflect the current status of git? Is their
> >>assessment of git's rename capability correct?
> >
> >
> > For example simple namespace for git: you can use shortened sha1
> > (even to only 6 characters, although usually 8 are used), you can
> > use tags, you can use ref^m~n syntax.
>
> Bazaar's namespace is "simple" because all branches can be named by a
> URL, and all revisions can be named by a URL + a number.
Well, all refs (branches and tags) are named by [relative] path. So for
example we can have 'master', 'next', 'jc/diff' branches, 'v1.4.0' and
'examples/tag' tags. Cogito for example uses <repository URL>#<branch>
syntax.
> If that's true of Git, then it certainly has a simple namespace. Using
> eight-digit hex values doesn't sound simple to me, though.
Well, <ref>~<n> means <n>-th _parent_ of a given ref, which for branches
(which constantly change) is a moving target.
There was proposal to add some kind of serial number to git (like
Subversion revision numbers) and even solution how to do this...
but one must realize that any serial number must be _local_ to the
repository. One cannot have universally valid revision numbers (even
only per branch) in distributed development. Subversion can do that only
because it is centralized SCM. Global numbering and distributed nature
doesn't mix... hence contents based sha1 as commit identifiers.
But this doesn't matter much, because you can have really lightweight
tags in git (especially now with packed refs support). So you can have
the namespace you want.
>> I'm not sure about "No" in "Supports Repository". Git supports multiple
>> branches in one repository, and what's better supports development using
>> multiple branches, but cannot for example do a diff or a cherry-pick
>> between repositories (well, you can use git-format-patch/git-am to
>> cherry-pick changes between repositories...).
>
> That sounds right. So those branches are persistent, and can be worked
> on independently?
Branches are persistent, have _separate_ (!) namespace (are not
incorporated in repository URL according to some kind of convention
like in Subversion), can be worked independently, you can easily
switch between branches in one working directory. Branches are cheap
in git (notion of topic branches).
I wonder if any SCM other than git has easy way to "rebase" a branch,
i.e. cut branch at branching point, and transplant it to the tip
of other branch. For example you work on 'xx/topic' topic branch,
and want to have changes in those branch but applied to current work,
not to the version some time ago when you have started working on
said feature.
What your comparison matrick lacks for example is if given SCM
saves information about branching point and merges, so you can
get where two branches diverged, and when one branch was merged into
another.
>> About "checkouts", i.e. working directories with repository elsewhere:
>> you can use GIT_DIR environmental variable or "git --git-dir" option,
>> or symlinks, and if Nguyen Thai Ngoc D proposal to have .gitdir/.git
>> "symref"-like file to point to repository passes, we can use that.
>
> It sounds like the .gitdir/.git proposal would give Git "checkouts", by
> our meaning of the term.
Actually it is better to work with clone of repository, perhaps either
symlinking object database, or by alternates mechanism (with alternates
repositories would share old history, but gather new independetly
I think).
>> Git doesn't have some "plugin framework", but because it has many
>> "plumbing" commands, it is easy to add new commands, and also new
>> merge strategies, using shell scripts, Perl, Python and of course C.
>> So the answer would be "Somewhat", as git has plugable merge strategies,
>> or even "Yes" at it is easy to add new git command.
>
> It sounds like you're saying it's extensible, not that it supports
> plugins. Plugins have very simple installation requirements. They can
> provide merge strategies, repository types, internet protocols, new
> commands, etc., all seamlessly integrated.
Plugins = API + detection ifrastructure + loading on demand.
Git has API, has a kind of detection ifrastructure (for commands and
merge strategies only), doesn't have loading on demand. You can
easily provide new commands (thanks to git wrapper) and new merge
strategies.
Does git needs "plugin framework"? I'm not sure. Now it is like
Linux kernel without loadable modules support...
> What you're describing actually sounds like the Arch approach to
> extensibility: provide a whole bunch of basic commands and let users
> build an RCS on top of that.
>
> As the author of two different Arch front-ends, I can say I haven't
> found that approach satisfactory. Invoking multiple commands tends
> re-invoke the same validation routines over and over, killing
> efficiency, and diagnostics tend to be pretty poorly integrated.
Actually I think it is how git was made. First came low level stuff,
"plumbing" in git parlance. Then there were scripts which used those
low level commands. There is ongoing project to rewrite them as builtin
commands (written in C); many of them got rewritten.
When git had very few higher level commands, here came git-pasky,
later renamed to Cogito; higher level SCM built on top of Git (in bash
shell). Now core git contains many high level commands, porcelanish
in git jargon.
Well, there is also StGit and it's alternative pg (Patchy Git), which
implement Quilt-like functionality (patch management) on top of Git.
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: git-diff-tree inordinately (O(M*N)) slow on files with many changes
From: Junio C Hamano @ 2006-10-16 22:53 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git, Davide Libenzi, Jim Meyering
In-Reply-To: <Pine.LNX.4.64.0610161130090.3962@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> Junio, I think this is worthy to go in before a 1.4.3 release. Possibly
> even back-ported to earlier trees.
Thanks for resolving this quickly; I was (am still somewhat)
down sick today and missed all the excitement.
> Quite frankly, I prefer my previous patch more, it just avoids that whole
> problem, and two shifts and adds (even with a conditional) are often
> faster than a full 64-bit multiply.
I agree (although I am not sure about the "do it twice for
small" bit), and I think Davide agrees with you in his reply:
Davide Libenzi <davidel@xmailserver.org> writes:
> On Mon, 16 Oct 2006, Linus Torvalds wrote:
> ...
> I ended up using this one:
>
> #define XDL_HASHLONG(v, b) ((((unsigned long) (v) >> ((CHAR_BIT * sizeof(unsigned long)) - (b))) + \
> (unsigned long) (v)) & ((1UL << (b)) - 1))
so I am inclined to apply Davide's version, but I am going to
bed again now...
^ permalink raw reply
* Re: VCS comparison table
From: Jakub Narebski @ 2006-10-16 22:53 UTC (permalink / raw)
To: git; +Cc: bazaar-ng
In-Reply-To: <45340949.9070606@shadowen.org>
Andy Whitcroft wrote:
> Aaron Bentley wrote:
>
>>>> Git supports renames in its own way; it doesn't use file ids, nor
>>>> remember renames (the new "note" header for use e.g. by porcelains
>>>> didn't pass if I remember correctly). But it does *detect* moving
>>>> _contents_, and even *copying* _contents_ when requested. And of
>>>> course it detect renames in merges.
>>
>> You'll note we referred to that bevhavior on the page. We don't think
>> what Git does is the same as supporting renames. AIUI, some Git users
>> feel the same way.
>
> In my experience there are two key features to rename support. The
> first that files move about efficiently ie. we don't have to carry a
> different copy of the same file for each name it has had, this git
> handles nicely. The second is the seemless following of history 'back',
> this git does not do trivially (when limited to specific files). git
> log on a renamed file pretty much stops at the rename point and you have
> deal with it yourself.
Both git log and git diff follows renames (with -M) and even copies
(with -C), but path _limiter_ doesn't follow renames. There is proposal
to add --follow option to git rev-list to follow specified paths. There was
a patch adding this option here on git mailing list (check archives), not
added because it was fairly intrusive and not complete solution IIRC.
I'd say that the second part is _partially_ supported, as we can follow
history of renamed file with pathlimit, detect that file was renamed, and
follow using previous name as pathlimit. For example if you know all the
names the file had through history, you can get whole history providing all
those names as pathlimit (well, unless there is some conflict like creating
new file with the same name as file before rename; something that all
file-id based solutions have problem with).
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* Re: VCS comparison table
From: Andy Whitcroft @ 2006-10-16 22:35 UTC (permalink / raw)
To: Aaron Bentley; +Cc: Jakub Narebski, bazaar-ng, git
In-Reply-To: <45340713.6000707@utoronto.ca>
Aaron Bentley wrote:
>>> Git supports renames in its own way; it doesn't use file ids, nor
>>> remember renames (the new "note" header for use e.g. by porcelains
>>> didn't pass if I remember correctly). But it does *detect* moving
>>> _contents_, and even *copying* _contents_ when requested. And of
>>> course it detect renames in merges.
>
> You'll note we referred to that bevhavior on the page. We don't think
> what Git does is the same as supporting renames. AIUI, some Git users
> feel the same way.
In my experience there are two key features to rename support. The
first that files move about efficiently ie. we don't have to carry a
different copy of the same file for each name it has had, this git
handles nicely. The second is the seemless following of history 'back',
this git does not do trivially (when limited to specific files). git
log on a renamed file pretty much stops at the rename point and you have
deal with it yourself.
I would love to see someone respond with a pickaxe like command line
which would list each and every change and its origin though merges and
the like.
Hmmm.
-apw
^ permalink raw reply
* Re: VCS comparison table
From: Aaron Bentley @ 2006-10-16 22:26 UTC (permalink / raw)
To: Jakub Narebski; +Cc: bazaar-ng, git
In-Reply-To: <egr3ud$nqm$1@sea.gmane.org>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Jakub Narebski wrote:
>>Does it accurately reflect the current status of git? Is their
>>assessment of git's rename capability correct?
>
>
> For example simple namespace for git: you can use shortened sha1
> (even to only 6 characters, although usually 8 are used), you can
> use tags, you can use ref^m~n syntax.
Bazaar's namespace is "simple" because all branches can be named by a
URL, and all revisions can be named by a URL + a number.
If that's true of Git, then it certainly has a simple namespace. Using
eight-digit hex values doesn't sound simple to me, though.
> I'm not sure about "No" in "Supports Repository". Git supports multiple
> branches in one repository, and what's better supports development using
> multiple branches, but cannot for example do a diff or a cherry-pick
> between repositories (well, you can use git-format-patch/git-am to
> cherry-pick changes between repositories...).
That sounds right. So those branches are persistent, and can be worked
on independently?
> About "checkouts", i.e. working directories with repository elsewhere:
> you can use GIT_DIR environmental variable or "git --git-dir" option,
> or symlinks, and if Nguyen Thai Ngoc D proposal to have .gitdir/.git
> "symref"-like file to point to repository passes, we can use that.
It sounds like the .gitdir/.git proposal would give Git "checkouts", by
our meaning of the term.
> Partial checkouts are only partially supported as of now; it means
> you have to do some lowe level stuff to do partial checkout, and be
> carefull when comitting. BTW it depends what you mean by partial
> checkout, but they are somewhat incompatibile with atomic commits
> to snapshot based repository.
Yes, I'm very much aware of that tension. It will be fun when Bazaar
tries to support that... :-)
> Git supports renames in its own way; it doesn't use file ids, nor
> remember renames (the new "note" header for use e.g. by porcelains
> didn't pass if I remember correctly). But it does *detect* moving
> _contents_, and even *copying* _contents_ when requested. And of
> course it detect renames in merges.
You'll note we referred to that bevhavior on the page. We don't think
what Git does is the same as supporting renames. AIUI, some Git users
feel the same way.
> Git doesn't have some "plugin framework", but because it has many
> "plumbing" commands, it is easy to add new commands, and also new
> merge strategies, using shell scripts, Perl, Python and of course C.
> So the answer would be "Somewhat", as git has plugable merge strategies,
> or even "Yes" at it is easy to add new git command.
It sounds like you're saying it's extensible, not that it supports
plugins. Plugins have very simple installation requirements. They can
provide merge strategies, repository types, internet protocols, new
commands, etc., all seamlessly integrated.
What you're describing actually sounds like the Arch approach to
extensibility: provide a whole bunch of basic commands and let users
build an RCS on top of that.
As the author of two different Arch front-ends, I can say I haven't
found that approach satisfactory. Invoking multiple commands tends
re-invoke the same validation routines over and over, killing
efficiency, and diagnostics tend to be pretty poorly integrated.
Aaron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFFNAb90F+nu1YWqI0RAvRDAJ9HHHdbhT1+aA3wOGeuUDkjRIr7BQCcDBKB
cL+DAy5GdTDk8Iz9TUkQ//M=
=AJAu
-----END PGP SIGNATURE-----
^ permalink raw reply
* RE: [RFH] git-svn documentation [was Re: git-svn and u-boot broken]
From: Joakim Tjernlund @ 2006-10-16 21:44 UTC (permalink / raw)
To: 'Eric Wong'; +Cc: git
In-Reply-To: <20061016183101.GL27128@hand.yhbt.net>
> Joakim Tjernlund <Joakim.Tjernlund@transmode.se> wrote:
> > Eric Wong wrote:
> > > I would do something like this:
> > >
> > > ... (same stuff as above before with svn setup...)
> > > git clone $ORG_REPO $GIT_REPO
> > > cd $GIT_REPO
> > > git-svn init "$REPO"/trunk
> > > git-svn fetch
> > >
> > > # sync the SVN repo with initial-uboot
> > > # this will just commit a snapshot, without history,
> which I assume
> > > # is what you want.
> > > git-branch initial-uboot f5e0d03970409feb3c77ab0107d5dece6b7d45c9
> > > git-svn commit initial-uboot
> > > git checkout -b svn-branch remotes/git-svn
> > > git-pull . tmcu2
> > >
> > > # this should work assuming the path from
> initial-uboot..tmcu2 is linear
> > > # use gitk initial-uboot..tmcu2 to check
> > > git-svn dcommit
> >
> > Great! This was exactly what I wanted, thanks. I never
> realized that one should
> > do git-svn commit initial-uboot to get that single commit.
> > I also replaced git-svn dcommit with git-svn commit
> remotes/git-svn..svn-branch
> > as I don't have that version yet.
> >
> > You should add this as an example I think.
> >
> > Can I ask for an example that used multi-init and
> multi-fetch? I tried, but
> > could not make it work.
>
> git-svn multi-init https://svn.musicpd.org/mpd -T trunk -t tags -b branches
> git-svn multi-fetch
This is how far I got too(sorry for beeing unclear). It is the
remaing bits that I got stuck on. How would the remaining git-svn
commands look like in the above example?
>
> In the latest git-svn (should be in 1.4.3), you can re-run 'git-svn
> multi-init' with no arguments to discover new tags+branches.
>
> Anybody willing to supply patches for better documentation? I'll be
> quite busy with other projects the next two weeks, asciidoc is quite
> slow for me; but I'd like to have better docs for git-svn in 1.4.3.
That would be great, I am still very much in the dark.
Jocke
^ permalink raw reply
* Re: git-diff-tree inordinately (O(M*N)) slow on files with many changes
From: Jakub Narebski @ 2006-10-16 20:29 UTC (permalink / raw)
To: git
In-Reply-To: <Pine.LNX.4.64.0610161225470.7697@alien.or.mcafeemobile.com>
Davide Libenzi wrote:
> I ended up using this one:
>
> #define XDL_HASHLONG(v, b) ((((unsigned long) (v) >> ((CHAR_BIT *
sizeof(unsigned long)) - (b))) + \
> (unsigned long) (v)) & ((1UL << (b)) - 1))
>
> The GR_PRIME selection does not make me feel good, and the 'static inline'
> is puked-over by certain C compilers. It'd be probably fine to just use a
> simple function, though the above should work just fine.
>
> real 0m0.665s
> user 0m0.655s
> sys 0m0.010s
>
> (Opteron 252)
Could you please do and post benchmarks for other solutions?
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* Re: git-diff-tree inordinately (O(M*N)) slow on files with many changes
From: Davide Libenzi @ 2006-10-16 19:44 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Junio C Hamano, Jim Meyering, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0610161130090.3962@g5.osdl.org>
On Mon, 16 Oct 2006, Linus Torvalds wrote:
>
> Junio, I think this is worthy to go in before a 1.4.3 release. Possibly
> even back-ported to earlier trees. Anything that causes an almost two
> orders of magnitude slowdown (even if it's just on 64-bit architectures
> and most people won't necessarily compile git that way) is worth fixing
> pronto.
I ended up using this one:
#define XDL_HASHLONG(v, b) ((((unsigned long) (v) >> ((CHAR_BIT * sizeof(unsigned long)) - (b))) + \
(unsigned long) (v)) & ((1UL << (b)) - 1))
The GR_PRIME selection does not make me feel good, and the 'static inline'
is puked-over by certain C compilers. It'd be probably fine to just use a
simple function, though the above should work just fine.
real 0m0.665s
user 0m0.655s
sys 0m0.010s
(Opteron 252)
- Davide
^ permalink raw reply
* Re: git-diff-tree inordinately (O(M*N)) slow on files with many changes
From: Linus Torvalds @ 2006-10-16 18:51 UTC (permalink / raw)
To: Junio C Hamano, Davide Libenzi; +Cc: Jim Meyering, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0610161109430.7697@alien.or.mcafeemobile.com>
Junio, I think this is worthy to go in before a 1.4.3 release. Possibly
even back-ported to earlier trees. Anything that causes an almost two
orders of magnitude slowdown (even if it's just on 64-bit architectures
and most people won't necessarily compile git that way) is worth fixing
pronto.
On Mon, 16 Oct 2006, Davide Libenzi wrote:
>
> Yeah, using an appropriate golden ratio prime for 64 bits fixes it. I
> think it's the best/minimal fix (use 0x9e37fffffffc0001UL, like the
> kernel does).
Ok. But then you need something like the appended to avoid warnings..
(This is the only nice portable way to figure out at compile-time whether
"unsigned long" is more than 32 bits that I can come up with: everything
that uses actual C expressions ends up warning about integers not fitting
etc)
Quite frankly, I prefer my previous patch more, it just avoids that whole
problem, and two shifts and adds (even with a conditional) are often
faster than a full 64-bit multiply.
Linus
---
diff --git a/xdiff/xmacros.h b/xdiff/xmacros.h
index 4c2fde8..38f8f93 100644
--- a/xdiff/xmacros.h
+++ b/xdiff/xmacros.h
@@ -23,8 +23,13 @@
#if !defined(XMACROS_H)
#define XMACROS_H
+#include <limits.h>
+#if LONG_MAX > 2147483647ul
+#define GR_PRIME 0x9e37fffffffc0001UL
+#else
#define GR_PRIME 0x9e370001UL
+#endif
#define XDL_MIN(a, b) ((a) < (b) ? (a): (b))
^ permalink raw reply related
* Re: git-diff-tree inordinately (O(M*N)) slow on files with many changes
From: Jim Meyering @ 2006-10-16 18:43 UTC (permalink / raw)
To: Davide Libenzi; +Cc: Linus Torvalds, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0610161129350.7697@alien.or.mcafeemobile.com>
Davide Libenzi <davidel@xmailserver.org> wrote:
...
> No, the patch is broken. It will discard *any* line seen at least two
> times, that is an extremely low threashold.
Oh! I see it now. Thanks.
^ permalink raw reply
* Re: git-diff-tree inordinately (O(M*N)) slow on files with many changes
From: Davide Libenzi @ 2006-10-16 18:41 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Jim Meyering, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0610161100070.3962@g5.osdl.org>
On Mon, 16 Oct 2006, Linus Torvalds wrote:
> On Mon, 16 Oct 2006, Linus Torvalds wrote:
> >
> > So just making GR_PRIME be a bigger value on a 64-bit architecture would
> > not have fixed it.
>
> Side note: in _practice_ I think it would have fixed it. The "not mixing
> in high bits" is not a real problem if the original hash-value has a good
> distribution of bits, which I think we do have. So it's unclear whether we
> even need any mixing in of bits at all, and it's possible that it would be
> fine to just have
>
> #define XDL_HASHLONG(v,b) ((unsigned long)(v) & ((1ul << (b))-1))
>
> which is simpler than my patch.
>
> I prefer the mixing in of high bits just because it can help if the
> original hash was bad (or had a tendency to have patterns in the low bits,
> which could be the case). But I'm not sure xdiff actually needs it in this
> case.
ATM, I added AC_CHECK_SIZEOF(long) inside libxdiff's configure.in, and I
have (inside xmacros.h):
#if SIZEOF_LONG == 4
#define GR_PRIME 0x9e370001UL
#else
#define GR_PRIME 0x9e37fffffffc0001UL
#endif
I'm also looking into streamlining the discard loop to reuse information
collected during the context-setup phase ...
- Davide
^ 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