Git development
 help / color / mirror / Atom feed
* Re: VCS comparison table
From: Matthieu Moy @ 2006-10-17 10:47 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: Robert Collins, bazaar-ng, git, Jakub Narebski
In-Reply-To: <4534AB8B.8030505@op5.se>

Andreas Ericsson <ae@op5.se> writes:

> Robert Collins wrote:
>> On Tue, 2006-10-17 at 11:20 +0200, Jakub Narebski wrote:
>>>           ---- time --->
>>>
>>>     --*--*--*--*--*--*--*--*--*-- <branch>
>>>           \            /
>>>            \-*--X--*--/
>>>
>>> The branch it used to be on is gone...
>>
>> In bzr 0.12 this is :
>> 2.1.2
>>
>
> Would it be a different number in a different version of bazaar?

I can't say for bzr 0.>12 which do not exist ;-)

For previous versions, it didn't have that "simple" number, and you
had to use the rev-id.

-- 
Matthieu

^ permalink raw reply

* Re: VCS comparison table
From: Matthias Kestenholz @ 2006-10-17 10:45 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Sean, Aaron Bentley, bazaar-ng, git
In-Reply-To: <Pine.LNX.4.63.0610171229160.14200@wbgn013.biozentrum.uni-wuerzburg.de>

Hi,

On Tue, 2006-10-17 at 12:30 +0200, Johannes Schindelin wrote:
> Hi,
> 
> On Tue, 17 Oct 2006, Sean wrote:
> 
> > On Tue, 17 Oct 2006 00:24:15 -0400
> > Aaron Bentley <aaron.bentley@utoronto.ca> wrote:
> > 
> > > - - you can have working trees on local systems while having the
> > >   repository on a remote system.  This makes it easy to work on one
> > >   logical branch from multiple locations, without getting out of sync.
> > 
> > That is a very nice feature.  Git would be improved if it could
> > support that mode of operation as well.
> 
> It would also make things slow as hell. How do you deal with something 
> like annotate in such a setup?

You'd probably have to do all processing server-side (git log, blame,
merges... like in subversion, where you can merge and rename/move files
remotely, IIRC). Of course, all the things which make git really useful
for me (gitk, git log with all its arguments etc.) would not be
available. Cheap checkouts would be made possible easily that way at the
cost of higher server load and an abstraction layer over network for
object access.

I don't know if that sounds reasonable at all.

	Matthias

^ permalink raw reply

* Re: [PATCH] nice ftplugin for vim, that shows the commited diff in a split'ed buffer.
From: Pierre Habouzit @ 2006-10-17 10:38 UTC (permalink / raw)
  To: Peter Baumann; +Cc: git, Jeff King
In-Reply-To: <802d21790610170122j6191ba51l2c39d3bc6a3475b@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 3826 bytes --]

Le mar 17 octobre 2006 10:22, Peter Baumann a écrit :
> 2006/10/17, Pierre Habouzit <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
>
> I find it confusing that you split vertically, especially if I work
> in small terminals.
> I would prefere a horizontal split, thats why I changed it to the way
> to the way it is
> handled in the svn.vim commit case:
>
> below new
>
> > +    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>"
>
> Why changing directory? I had to remove the cd .. to make it work.
> Otherwise git diff couldn't find the repository.

because for me, wherever I'm from, the cwd is .git/ but it's maybe due 
to the fact that I use autochdir, I don't know.

-- 
·O·  Pierre Habouzit
··O                                                madcoder@debian.org
OOO                                                http://www.madism.org

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: VCS comparison table
From: Sean @ 2006-10-17 10:35 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Aaron Bentley, bazaar-ng, git
In-Reply-To: <Pine.LNX.4.63.0610171229160.14200@wbgn013.biozentrum.uni-wuerzburg.de>

On Tue, 17 Oct 2006 12:30:27 +0200 (CEST)
Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:

> It would also make things slow as hell. How do you deal with something 
> like annotate in such a setup?

Some commands like annotate might not make any sense in such a set up.

But one way to get the same (perhaps even better) feature into git 
would be to support shallow clones, in which case even annotate would
continue to work even if somewhat crippled by the lack of a complete
history.

Sean

^ permalink raw reply

* Re: VCS comparison table
From: Johannes Schindelin @ 2006-10-17 10:30 UTC (permalink / raw)
  To: Sean; +Cc: Aaron Bentley, bazaar-ng, git
In-Reply-To: <BAYC1-PASMTP08A746E5FA6B87BC65BD37AE0E0@CEZ.ICE>

Hi,

On Tue, 17 Oct 2006, Sean wrote:

> On Tue, 17 Oct 2006 00:24:15 -0400
> Aaron Bentley <aaron.bentley@utoronto.ca> wrote:
> 
> > - - you can have working trees on local systems while having the
> >   repository on a remote system.  This makes it easy to work on one
> >   logical branch from multiple locations, without getting out of sync.
> 
> That is a very nice feature.  Git would be improved if it could
> support that mode of operation as well.

It would also make things slow as hell. How do you deal with something 
like annotate in such a setup?

Ciao,
Dscho

^ permalink raw reply

* Re: VCS comparison table
From: Sean @ 2006-10-17 10:23 UTC (permalink / raw)
  To: Aaron Bentley; +Cc: Johannes Schindelin, Jakub Narebski, bazaar-ng, git
In-Reply-To: <4534656B.7080105@utoronto.ca>

On Tue, 17 Oct 2006 01:08:59 -0400
Aaron Bentley <aaron.bentley@utoronto.ca> wrote:

> I can use the 'bzr missing' command to check whether my branch is in
> sync with a remote branch.  Or I can use the 'pull' command to update my
> branch to a given revno in a remote branch.

The "bzr missing" command sounds like a handy one.  

Someone on the xorg mailing list was recently lamenting that git does not
have an easy way to compare a local branch to a remote one.  While this
turns out to not be a big problem in git, it might be nice to have such
a command.

Sean

^ permalink raw reply

* Re: VCS comparison table
From: Sean @ 2006-10-17 10:23 UTC (permalink / raw)
  To: Aaron Bentley; +Cc: Linus Torvalds, Jakub Narebski, bazaar-ng, git
In-Reply-To: <45345AEF.6070107@utoronto.ca>

On Tue, 17 Oct 2006 00:24:15 -0400
Aaron Bentley <aaron.bentley@utoronto.ca> wrote:

> The key thing about a checkout is that it's stored in a different
> location from its repository.  This provides a few benefits:
> 
> - - you can publish a repository without publishing its working tree,
>   possibly using standard mirroring tools like rsync.

Yeah, even in git you typically don't publish your working tree when
making it available for cloning.  In fact the native git network
protocol doesn't even have a way to transfer working trees.

> - - you can have working trees on local systems while having the
>   repository on a remote system.  This makes it easy to work on one
>   logical branch from multiple locations, without getting out of sync.

That is a very nice feature.  Git would be improved if it could
support that mode of operation as well.

> - - you can use a checkout to maintain a local mirror of a read-only
>   branch (I do this with http://bazaar-vcs.com/bzr/bzr.dev).

I'm not sure what you mean here.  A bzr checkout doesn't have any history
does it?  So it's not a mirror of a branch, but just a checkout of the
branch head?

If so, Git can export a tarball of a branch (actually a snapshot as at
any given commit) which can be mirrored out.

Sean

^ permalink raw reply

* Re: VCS comparison table
From: Andreas Ericsson @ 2006-10-17 10:08 UTC (permalink / raw)
  To: Robert Collins; +Cc: Jakub Narebski, Aaron Bentley, bazaar-ng, git
In-Reply-To: <1161078035.9020.73.camel@localhost.localdomain>

Robert Collins wrote:
> On Tue, 2006-10-17 at 11:20 +0200, Jakub Narebski wrote:
>>           ---- time --->
>>
>>     --*--*--*--*--*--*--*--*--*-- <branch>
>>           \            /
>>            \-*--X--*--/
>>
>> The branch it used to be on is gone...
> 
> In bzr 0.12 this is :
> 2.1.2
> 

Would it be a different number in a different version of bazaar?

> (assuming the first * is numbered '1'.)
> 
> These numbers are fairly stable, in particular everything's number in
> the mainline will be the same number in all the branches created from it
> at that point in time, but a branch that initially creates a revision or
> obtains it before the mainline will have a different number until they
> syncronise with the mainline via pull.
> 

So basically anyone can pull/push from/to each other but only so long as 
they decide upon a common master that handles synchronizing of the 
number part of the url+number revision short-hands?

One thing that's been nagging me is how you actually find out the 
url+number where the desired revision exists. That is, after you've 
synced with master, or merged the mothership's master-branch into one of 
your experimental branches where you've done some work that went before 
mothership's master's current tip, do you have to have access to the 
mothership's repo (as in, do you have to be online) to find out the 
number part of url+number shorthand, or can you determine it solely from 
what you have on your laptop?

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

^ permalink raw reply

* Re: VCS comparison table
From: Jakub Narebski @ 2006-10-17 10:06 UTC (permalink / raw)
  To: git; +Cc: bazaar-ng
In-Reply-To: <1161077866.9020.69.camel@localhost.localdomain>

Robert Collins wrote:

> On Tue, 2006-10-17 at 01:19 +0200, Jakub Narebski wrote:
>> 
>> 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. 
> 
> Precisely how does this rebase operate in git ? 
> Does it preserve revision ids for the existing work, or do they all
> change?

Revision ids (commit ids) change of course. Therefore rebasing published
branches is not recommended, as it is in fact rewriting history.

It is however recommended before sending _series_ of patches (work on that
series should be done using topic branch) to rebase topic branch they sit
on for the patches to apply cleanly on top of current work. Or use StGit or
other Quilt (patch management) equivalent.

> bzr has a graft plugin which walks one branch applying all its changes
> to another preserving the users metadata but changing the uuids for
> revisions. 

This looks like "bzr graft" is the same as "git rebase". It can deal with
conflict, cannot it?


P.S. It looks like we have yet another terminology conflict. In git "graft"
means "history graft" i.e. file which changes parents of some commits. For
example if we have historical repositoy and current repositoy we can join
together using grafts (otherwise we would need to rewrite history, as sha1
which serves as commit id includes parents information), e.g.

   x--*--*--*--*....x--*--*--*--*

    historical         current

where 'x' is 'root' (parentless) commit, '--' denotes parentship, and '....'
denotes "history graft".      
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: VCS comparison table
From: Sean @ 2006-10-17 10:01 UTC (permalink / raw)
  To: Robert Collins; +Cc: Jakub Narebski, Aaron Bentley, bazaar-ng, git
In-Reply-To: <1161077866.9020.69.camel@localhost.localdomain>

On Tue, 17 Oct 2006 19:37:45 +1000
Robert Collins <robertc@robertcollins.net> wrote:

> Precisely how does this rebase operate in git ? 
> Does it preserve revision ids for the existing work, or do they all
> change?
> 
> bzr has a graft plugin which walks one branch applying all its changes
> to another preserving the users metadata but changing the uuids for
> revisions. 

git rebase does exactly the same as you describe, including changing
the sha1 for each commit it moves.

Sean

^ permalink raw reply

* Re: VCS comparison table
From: Andreas Ericsson @ 2006-10-17  9:59 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: bazaar-ng, git
In-Reply-To: <200610171120.09747.jnareb@gmail.com>

Jakub Narebski wrote:
> 
> About new command detection: if you put program named git-<command>
> in directory with the rest of git commands, then you can call it
> as "git <command>" using git wrapper. I think.
> 

Yup. The new command will also automagically appear in the "git help -a" 
output. Those two functions have been available since the C wrapper was 
born, although "git help -a" was the only available output for "command 
not found" until someone introduced the more newbie-friendly list that 
pops up now adays.

^ permalink raw reply

* Re: VCS comparison table
From: Jakub Narebski @ 2006-10-17  9:45 UTC (permalink / raw)
  To: git; +Cc: bazaar-ng
In-Reply-To: <1161077599.9020.66.camel@localhost.localdomain>

Robert Collins wrote:

> On Tue, 2006-10-17 at 01:45 +0200, Johannes Schindelin wrote:
>> 
>> 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_!
> 
> Just a small nit here: bzr does /not/ record the move of every file: it
> records the rename of folder1 to folder2. One piece of data is all thats
> recorded - no new manifest for the subdirectory is needed.
> 
> Of course, a user can choose to move all the contents of a folder and
> not the folder itself - its up to the user.
> 
> By recording the folder rename rather than the contents rename, we get
> merges of new files added to folder1 in other branches come into folder2
> automatically, without needing to do arbitrarily deep history processing
> to determine that.

Hmmm... I wonder how well git manages that (merge with renamed directory).

  folder1/a  -->  folder2/a  --------> folder2/a
  folder1/b  -->  folder2/b       /    folder2/b
      \                          /     folder2/c
       \------->  folder1/a  ---/
                  folder1/b
                  folder1/c


I wonder how bzr manages "separate some files into subdirectory" (and how
well git does that), i.e. we have

   sub-file1
   sub-file2
   filea
   fileb

In the 'main' branch we separated "sub-*" files into subdirectory

   sub/file1
   sub/file2
   filea
   fileb

How would that merge with adding new sub-* file on the branch to be merged?

   sub-file1
   sub-file2
   sub-file3
   filea
   fileb


Or how bzr manages sub-level movement, such as splitting file into two,
or joining two files into one file.


P.S. is anyone working on --follow option for renames following path
limiting?
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: VCS comparison table
From: Robert Collins @ 2006-10-17  9:40 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Aaron Bentley, bazaar-ng, git
In-Reply-To: <200610171120.09747.jnareb@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 726 bytes --]

On Tue, 2006-10-17 at 11:20 +0200, Jakub Narebski wrote:
> 
>           ---- time --->
> 
>     --*--*--*--*--*--*--*--*--*-- <branch>
>           \            /
>            \-*--X--*--/
> 
> The branch it used to be on is gone...

In bzr 0.12 this is :
2.1.2

(assuming the first * is numbered '1'.)

These numbers are fairly stable, in particular everything's number in
the mainline will be the same number in all the branches created from it
at that point in time, but a branch that initially creates a revision or
obtains it before the mainline will have a different number until they
syncronise with the mainline via pull.

-Rob
-- 
GPG key available at: <http://www.robertcollins.net/keys.txt>.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply

* Re: VCS comparison table
From: Robert Collins @ 2006-10-17  9:37 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Aaron Bentley, bazaar-ng, git
In-Reply-To: <200610170119.09066.jnareb@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 799 bytes --]

On Tue, 2006-10-17 at 01:19 +0200, Jakub Narebski wrote:
> 
> 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. 

Precisely how does this rebase operate in git ? 
Does it preserve revision ids for the existing work, or do they all
change?


bzr has a graft plugin which walks one branch applying all its changes
to another preserving the users metadata but changing the uuids for
revisions. 

-Rob

-- 
GPG key available at: <http://www.robertcollins.net/keys.txt>.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply

* Re: VCS comparison table
From: Robert Collins @ 2006-10-17  9:33 UTC (permalink / raw)
  To: bazaar-ng@lists.canonical.com; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0610170128350.14200@wbgn013.biozentrum.uni-wuerzburg.de>

[-- Attachment #1: Type: text/plain, Size: 1208 bytes --]

On Tue, 2006-10-17 at 01:45 +0200, Johannes Schindelin wrote:
> 
> 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_!

Just a small nit here: bzr does /not/ record the move of every file: it
records the rename of folder1 to folder2. One piece of data is all thats
recorded - no new manifest for the subdirectory is needed.

Of course, a user can choose to move all the contents of a folder and
not the folder itself - its up to the user.

By recording the folder rename rather than the contents rename, we get
merges of new files added to folder1 in other branches come into folder2
automatically, without needing to do arbitrarily deep history processing
to determine that.

This also does not prevent us doing history analysis as well, to
determine other interesting things - such as cross file 'blame' as has
been mentioned in this thread. 

-Rob
-- 
GPG key available at: <http://www.robertcollins.net/keys.txt>.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply

* Re: [PATCH 1/2] Delete ref $frotz by moving ref file to "deleted-$frotz~ref".
From: Jakub Narebski @ 2006-10-17  9:24 UTC (permalink / raw)
  To: git
In-Reply-To: <200610170626.25654.chriscool@tuxfamily.org>

Christian Couder wrote:

>> Ref deletion is an operation that happens far far rarer than
>> updates and lookups, and I deliberately chose to optimize for
>> the latter.
> 
> I think that the ref deletion usage depends on the policy of people using 
> git, and there may be people that delete a ref very often.
> 
> For example, when git becomes a major SCM, there may be people working on 
> big projects that want to create a new branch for each new bug and then 
> delete the branch when the code on the bug branch has been integrated into 
> a new release and the bug is closed.

So do not pack branches then, pack only tags.
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: VCS comparison table
From: Jakub Narebski @ 2006-10-17  9:20 UTC (permalink / raw)
  To: Aaron Bentley; +Cc: bazaar-ng, git
In-Reply-To: <45346290.6050300@utoronto.ca>

Aaron Bentley wrote:
> Jakub Narebski wrote:
>> Well, <ref>~<n> means <n>-th _parent_ of a given ref, which for branches
>> (which constantly change) is a moving target.
> 
> Ah.  Bazaar uses negative numbers to refer to <n>th parents, and
> positive numbers to refer to the number of commits that have been made
> since the branch was initialized.

How that works with branching point, and with merges? For example
in the case depicted below, how you refer to commit marked by X?

          ---- time --->

    --*--*--*--*--*--*--*--*--*-- <branch>
          \            /
           \-*--X--*--/

The branch it used to be on is gone...


Besides, in git commit object has pointers (in the form of sha1 ids)
to all its parents. So <ref>^ (parent of <ref>), or <ref>^<m> (m-th
parent of <ref>), or <ref>~<n> (n-th parent in 1st-parent lineage
of <ref>) are natural, and fast. <ref>+<n> (which would add yet another
character as forbidden in branch name) would need either serial number
(per repository or per branch) to commit id database, or getting full
history and looking it up in full history.

Branches in git are remembered not by their starting points, but by
their tips (ending points).

>> 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.
> 
> Sure.  Our UI approach is that unique identifiers can usefully be
> abstracted away with a combination of URL + number, in the vast
> majority of cases.

Git could do that too, by having file (files) with serial number
or branch/tag+serial number to commit id mapping. But this would
have to be local matter. And this would take some disk space, and
would seriously affect fetch performance (now git just downloads
what it doesn't have and dumps it into repository database).

BTW. what if repository is moved from one URL to another, for example
moving to different host? All "abstracted away" identifiers get
invalidated?

>> 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.
> 
> The nice thing about revision numbers is that they're implicit-- no one
> needs to take any action to update them, and so you can always use them.

Two words: post-commit hook. You can automate action of adding tags
(especially now with packed refs, which means that we can have huge number
of tags and this doesn't affect performance doue to I/O nor repository size)

>> 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.
> 
> If I understand correctly, in Bazaar, you'd just merge the current work
> into 'xx/topic'.

That is the alternate solution, but this would mean that merge would be
recorded (unless you squash it). And for published branches (like 'next'
for example) it is better solution, because rebase is in fact rewriting
history.

But rebase means that you had

                 A---B---C topic
                /
           D---E---F---G master

Rebasing 'topic' branch on top of master would mean that you would get

                         A'--B'--C' topic
                        /
           D---E---F---G master

where A', B', C' represent the same changeset as A, B, C up to resolved
conflicts.

And yes, that is "bzr graft"
  http://spacepants.org/src/bzrgraft/
equivalent. Do I understand correctly that this is third-party
contribution?

>> 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.
> 
> I'm not sure what you mean about divergence.  For example, Bazaar
> records the complete ancestry of each branch, and determining the point
> of divergence is as simple as finding the last common ancestor.  But are
> you considering only the initial divergence?  Or if the branches merge
> and then diverge again, would you consider that the point of divergence?
> 
> merge-point tracking is a prerequisite for Smart Merge, which does
> appear on our matrix.

I was talking about point-of-divergence (branching point, fork point)
tracking, and merge-point tracking (or saving merge information).

>> 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.
> 
> I'm not sure what you mean by API, unless you mean the commandline.  If
> that's what you mean, surely all unix commands are extensible in that
> regard.

I mean API in the most common sense. 

For commands written in C it means "engine" (plumbing) functions and
data structures which do most work, so writing new command means some
command specific code and calling some functions to do the work.

For commands written in shell it means having versatile plumbing
commands (like for example git-rev-parse, git-rev-list, git-merge-base,
git-cat-file, etc.) which can be joined together including pipes
(--stdin option, --revs option to some commands), and git-sh-setup,
common git shell setup code. 

For commands writtent in Perl it means the same, with Git.pm module
instead of git-sh-setup.


About new command detection: if you put program named git-<command>
in directory with the rest of git commands, then you can call it
as "git <command>" using git wrapper. I think.

About adding new merge strategies: no autodoetection, you would
have to add new merge strategu to git-merge.sh.
-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: On blame/pickaxe
From: Junio C Hamano @ 2006-10-17  9:03 UTC (permalink / raw)
  To: Luben Tuikov; +Cc: git
In-Reply-To: <20061016234547.21649.qmail@web31809.mail.mud.yahoo.com>

Luben Tuikov <ltuikov@yahoo.com> writes:

>> 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.

Working on a small example by hand is a good way to convince
yourself.  The whole point of "try to pass the blame, and take
the blame yourself only when you can't pass to anybody" is
precisely to handle the merges sanely.  The answer to your later
question also would become crystal clear with that exercise.

Suppose that we are looking at a merge that would give this in
its "git show" output:

diff --cc hello.c
index 3c27792,db3fdef..cec80d2
--- a/hello.c
+++ b/hello.c
@@@ -1,4 -1,6 +1,6 @@@
  int main(int ac, char **av)
  {
-       printf("hello, world.\n");
 -      const char *msg = "hello, world";
++      const char *msg = "hello, world.";
+ 
+       printf("%s\n", msg);
  }

First, we inspect the diff from the first parent:

        diff --git a/hello.c b/hello.c
        index 3c27792..cec80d2 100644
        --- a/hello.c
        +++ b/hello.c
        @@ -1,4 +1,6 @@
1        int main(int ac, char **av)
2        {
        -       printf("hello, world.\n");
3       +       const char *msg = "hello, world.";
4       +
5       +       printf("%s\n", msg);
6        }

That would find that lines 1, 2 and 6 came from the first parent
(line numbers are of the postimage; e.g. line 6 is the closing
brace).

We are still left with lines 3, 4, and 5.  So we will see the
difference from the second parent:

        diff --git a/hello.c b/hello.c
        index db3fdef..cec80d2 100644
        --- a/hello.c
        +++ b/hello.c
        @@ -1,6 +1,6 @@
1        int main(int ac, char **av)
2        {
        -       const char *msg = "hello, world";
3       +       const char *msg = "hello, world.";
4
5               printf("%s\n", msg);
6        }

It shows that lines 1, 2, 4, 5 and 6 are the same as the second
parent (again, line numbers are of the postimage).  This means
that we _could_ attribute line 1, 2 and 6 to the second parent
if we wanted to, but we have already passed blame for 1, 2 and 6
to the first parent [*1*] and only lines 4 and 5 are assigned to
the second parent.

At this point, we have no more parents to pass blame on and are
still left with line 3.  So we end up taking the blame for that
line ourselves.  The final blame output reflects that.

If you are interested, prepare an example repository using the
attached script, and try annotating E, like this:

	git pickaxe --not right~2 left -- E

This demonstrates the example in this message (first parent is
Right and the second is Left).

Annotating C with blame and pickaxe (use "-n -f" for clarity)
shows the limitation of the original 'blame' that can use only
one path per commit.  This is a corner case where two files
originally different in the common ancestor were later merged
into one.  pickaxe handles this case without -M.

	git blame -n -f C
        git pickaxe -n -f C

Annotating D with pickaxe with and without -M illustrates how
line movement is handled.

	git pickaxe -M D

Have fun.


[*1*] The really core part of git does not have any preference
among parents, but typically a merge commit is made with the
current branch head as its first parent and the other branch as
its second parent, so favoring the earlier parent over the later
ones makes a lot of sense in practice.  This is in line with
other parts of git, including the merge simplification done by
git-log.

-- 8< --
#!/bin/sh

test -d .git || {
	echo Run me in an empty directory.
	exit
}
git init-db

for i in 1 2 3 4 5 6 7 8 9 ; do echo line from initial $i ; done >A
for i in A B C D E F G H I ; do echo line from initial $i ; done >B
cp A D
cat >E <<EOF
int main(int ac, char **av)
{
	printf("hello, world\n");
}
EOF

git add A B D E
git commit --author='Initial <initial@author>' -m initial

git branch right
git branch left

# Left
git checkout left
for i in 1 2 3; do echo added by left; done >C
cat A >>C
rm -f A B
cat >E <<EOF
int main(int ac, char **av)
{
	const char *msg = "hello, world";

	printf("%s\n", msg);
}
EOF
git update-index --add --remove A B C E
git commit --author='Left <left@branch>' -m Left

# Right
git checkout right
cat B >C
for i in 1 2 3; do echo added by right; done >>C
rm -f A B
cat >E <<EOF
int main(int ac, char **av)
{
	printf("hello, world.\n");
}
EOF
git update-index --add --remove A B C E
git commit --author='Right <right@branch>' -m Right

echo "Merge -- this should fail which is expected and scripts fixes it up"
echo "Do not get alarmed with the error message."
git pull . left
echo "Fixing up..."
{
	git cat-file blob :3:C
	echo line by evil merge
	git cat-file blob :2:C
} >C
cat >E <<EOF
int main(int ac, char **av)
{
	const char *msg = "hello, world.";

	printf("%s\n", msg);
}
EOF
git update-index C E
git commit --author='Merge <merge@branch>' -m 'Changes are merged.'
rm -f C~*

{
	for i in 5 6 7; do echo line from initial $i ; done
	echo line modified while swapping 8
	for i in 9 1 2 3 4 ; do echo line from initial $i ; done
} >D

git update-index D
git commit --author='Swap <swap@branch>' -m 'Lines are swapped.'

echo "Now try annotating C, D and E with various options."

^ permalink raw reply

* Re: [RFC/PATCH] git-fetch: Use already fetched branch with the --local flag.
From: Santi Béjar @ 2006-10-17  8:36 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vbqobo1m1.fsf@assigned-by-dhcp.cox.net>

2006/10/17, Junio C Hamano <junkio@cox.net>:

[...]

>
> You have an upstream repository that has more than one branches
> you are interested in, say "master" and "next".  And you work on
> top of both of them, so you have two branches of your own that
> correspond to them.
>
> So you organize your remote section perhaps like this:
>
>         [remote."origin"]
>                 url = git://git.k.o/.../git.git/
>                 fetch = refs/heads/master:refs/remotes/origin/master
>                 fetch = refs/heads/next:refs/remotes/origin/next
>                 fetch = +refs/heads/pu:refs/remotes/origin/pu
>
>         [branch."master"]
>                 remote = origin
>                 merge = refs/heads/master
>
>         [branch."next"]
>                 remote = origin
>                 merge = refs/heads/next
>
> That is, your refs/heads/master corresponds to upstream's master
> branch and your next corresponds to upstream's next branch.
> When you are on your "master" you would merge changes made to
> upstream's master into it with "git pull".

Yes, that is.

>
>         By the way, could you add descriptions on remote.* to
>         Documentation/config.txt?
>

I'll try. Off-topic: Do you want also docs for the ^@ notation and an
implementation in git-rev-parse?

> After doing a "git pull" while on your "master" and finishing
> working on your "master", you might switch to your "next".  At
> that point, if you want to merge upstream changes without
> re-fetching, you can do either of the following:
>
>         git pull . remotes/origin/next
>         git pull --local
>
> (the former can be "git pull" if "branch.next.remote=.").
>
> I think this is the point of your two patches, and in that
> sense, the --local one makes "branch.remote=." patch
> unnecessary.

I see them differently. "branch.remote=." is when there is no upstream
(e.g., for your next and master branches in git.git).

>
> While these save typing on "git pull", two things bother me.
>
>  * the tool is not helping you decide if you can get away
>    without re-fetching.  you need to remember that (1) you
>    fetched from the upstream to update "master" recently _and_
>    (2) because of your [remote."origin"] configuration your
>    remotes/origin/next was updated while you pulled into your
>    "master".

You never know if you can get away without re-fetching (or I don't
parse this sentence :). The way I see it, you always us "git pull"
except when you want to merge the exactly the already fetch branch
because (1) you want to merge the same upstream as with other branch
(2) you don't have access to the remote repository (3)...

>
>  * while the workflow assumes that one local branch is tied
>    closely to one remote branch (in this example, tracked under
>    remotes/origin), the rest of the tools do not take advantage
>    of that assumption to help you decide what to do next.

This is the next item in my TODO :)
Next with a program similar to "svn info" showing misc info about a branch.

>
> For example, if each of your local branch is tied closely to one
> remote branch, you should be able to "git fetch" to update the
> tracking branches and then ask:
>
>  - what changes are in remote that I haven't merged?
>
>  - what happens when I pull --local right now?
>
>  - what changes if any are in mine alone missing from remote?
>
>  - can I push to remote right now (i.e. would it fast-forward)?
>
>  - how fresh is the tracking branch that corresponds to my
>    current branch?
>
> Right now, these require you to spell out the name of the
> tracking branch.  Assuming you are on your "next" branch:
>
>         git log ..remotes/origin/next
>         git log remotes/origin/next..
>         git log remotes/origin/next...next              [*1*]
>         git show-branch remotes/origin/next next
>         tail -n 1 .git/logs/remotes/origin/next
>
> would be the ways to ask the above questions (and the last one
> is unreadable unless you can do strptime in your head).
>
> Maybe we can introduce a new extended SHA-1 notation to mean
> "the tracking branch this branch usually merges from".  Then we
> can say:
>
>         git log ..^
>         git log ^..
>         git log ^...
>         git show-branch ^ next
>
> I am not sure '^' is syntactically viable, but hopefully you get
> the idea.

I get it. Another idea is to have a .git/ORIGIN that points to the
tracking branch so you could say:

         git log ..ORIGIN
         git log ORIGIN..
         git log ORIGIN...
         git show-branch ORIGIN next

One advantage is that it only needs changes to "git checkout" (and
possibly others but not to plumbing ones).
Another is that the ^ notation forces the low level tools to follow
configs in [branch."..."] and [remote."..."].
>
>
> [*1*] While three-dots symmetric difference is a nice addition
> made recently, I often find it irritating that the output does
> not tell which branch each of the commit is reachable from, and
> end up running show-branch, which does.  Would anybody have a
> clever idea to fix this cleanly?

I don't know if it is a clever idea but...

We could use the git-name-rev method:

$git log a...b
commit sha1 (a)
....

commit sha1 (a^)
....

commit sha1 (b^)
....

commit sha1 (b)
....

and without this when on both branches.

Santi

^ permalink raw reply

* Re: VCS comparison table
From: Jakub Narebski @ 2006-10-17  8:15 UTC (permalink / raw)
  To: Aaron Bentley; +Cc: bazaar-ng, git
In-Reply-To: <45346290.6050300@utoronto.ca>

Dnia wtorek 17. października 2006 06:56, Aaron Bentley napisał:
> Jakub Narebski wrote:
> > Well, <ref>~<n> means <n>-th _parent_ of a given ref, which for branches
> > (which constantly change) is a moving target.
> 
> Ah.  Bazaar uses negative numbers to refer to <n>th parents, and
> positive numbers to refer to the number of commits that have been made
> since the branch was initialized.
> 
> > 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.
> 
> Sure.  Our UI approach is that unique identifiers can usefully be
> abstracted away with a combination of URL + number, in the vast majority
> of cases.
> 
> > 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.
> 
> The nice thing about revision numbers is that they're implicit-- no one
> needs to take any action to update them, and so you can always use them.
> 
> > 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.
> 
> If I understand correctly, in Bazaar, you'd just merge the current work
> into 'xx/topic'.
> 
> > 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.
> 
> I'm not sure what you mean about divergence.  For example, Bazaar
> records the complete ancestry of each branch, and determining the point
> of divergence is as simple as finding the last common ancestor.  But are
> you considering only the initial divergence?  Or if the branches merge
> and then diverge again, would you consider that the point of divergence?
> 
> merge-point tracking is a prerequisite for Smart Merge, which does
> appear on our matrix.
> 
> > 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.
> 
> I'm not sure what you mean by API, unless you mean the commandline.  If
> that's what you mean, surely all unix commands are extensible in that
> regard.
> 
> Aaron
> 

^ permalink raw reply

* Re: VCS comparison table
From: Jakub Narebski @ 2006-10-17  8:30 UTC (permalink / raw)
  To: Aaron Bentley; +Cc: Linus Torvalds, bazaar-ng, git
In-Reply-To: <45345AEF.6070107@utoronto.ca>

Aaron Bentley wrote:
> Linus Torvalds wrote:

>> If you want a short, human-readable name, you _tag_ it. It takes all of a
>> hundredth of a second to to or so.
> 
> But tags have local meaning only, unless someone has access to your
> repository, right?

Tags are propagated during clone, and during fetch/pull (getting changes
from repository). So in that sense they are global.

If you don't publish your repository, then neither tags, nor <URL>+<rev no>
has any sense, any meaning to somebody other than local private repository.
 

>> 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.
> 
> The key thing about a checkout is that it's stored in a different
> location from its repository.  This provides a few benefits:
> 
> - you can publish a repository without publishing its working tree,
>   possibly using standard mirroring tools like rsync.

git clone --bare
 
> - you can have working trees on local systems while having the
>   repository on a remote system.  This makes it easy to work on one
>   logical branch from multiple locations, without getting out of sync.

In git we usually use "git clone --local" (with repository database
hardlinked) or "git clone --shared"/"git clone --reference <repository>"
(which automatically sets alternates, i.e. file pointing to alternate
repository database) for that. This way one gets his/her own refs
namespace, so two people can work on different branches simultaneously.

Alternate solution would be to symlink .git, or .git/objects (i.e.
repository "database").

> - you can use a checkout to maintain a local mirror of a read-only
>   branch (I do this with http://bazaar-vcs.com/bzr/bzr.dev).

In git you can access contents _without_ checkout/working area.
For example gitweb (one of git's web interfaces) uses only repository
database and doesn't need checkout/working area.

>> 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.
> 
> You can operate that way in bzr too, but I find it nicer to have one
> checkout for each active branch, plus a checkout of bzr.dev.  Our switch
> command also rewrites only the changed part of the working tree.

Luben (IIRC) works this way.

^ permalink raw reply

* Re: VCS comparison table
From: Martin Pool @ 2006-10-17  8:21 UTC (permalink / raw)
  To: Shawn Pearce; +Cc: Aaron Bentley, bazaar-ng, git, Jakub Narebski
In-Reply-To: <20061017052019.GB21210@spearce.org>

On 17 Oct 2006, Shawn Pearce <spearce@spearce.org> wrote:
> Aaron Bentley <aaron.bentley@utoronto.ca> wrote:
> > Jakub Narebski wrote:
> > > 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.
> > 
> > Sure.  Our UI approach is that unique identifiers can usefully be
> > abstracted away with a combination of URL + number, in the vast majority
> > of cases.
> 
> But this only works when the URL is public.  In Git I can just lookup
> the unique SHA1 for a revision in my private repository and toss it
> into an email with a quick copy and paste.  

Yes, but then people need to know how to get it out of your private
repository.  For stuff that goes into well-known repositories I suppose
it just propagates.

> With Bazaar it sounds like I'd have to do that relative to some known
> public repository, which just sounds like more work to me.

You can also name a revision using its UUID, in which case things will
work similarly to git.  We tend to often say "in r1234 of dev".

> But I don't want to see this otherwise interesting thread devolve into
> a "we do X better!" match so I'm not going to say anything further here.

Sure.

> > > 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.
> > 
> > If I understand correctly, in Bazaar, you'd just merge the current work
> > into 'xx/topic'.
> 
> Git has two approaches:
> 
>  - merge: The two independent lines of development are merged
>    together under a new single graph node.  This is a merge commit
>    and has two parent pointers, one for each independent line of
>    development which was combined into one.  Up to 16 independent
>    lines can be merged at once, though 12 is the record.
> 
>  - rebase: The commits from one line of development are replayed
>    onto a totally different line of development.  This is often
>    used to reapply your changes onto the upstream branch after the
>    upstream has changed but before you send your changes upstream.
>    It can often generate more readable commit history.
> 
> I believe what you are talking about in Bazaar is the former (merge)
> while what Jakub was talking about was the latter (rebase).

For the 'rebase' operation in Bazaar you can use 'bzr graft':

  http://spacepants.org/src/bzrgraft/

-- 
Martin

^ permalink raw reply

* Re: [PATCH] nice ftplugin for vim, that shows the commited diff in a split'ed buffer.
From: Peter Baumann @ 2006-10-17  8:22 UTC (permalink / raw)
  To: Pierre Habouzit; +Cc: git, Jeff King
In-Reply-To: <11610450701082-git-send-email-madcoder@debian.org>

2006/10/17, Pierre Habouzit <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

I find it confusing that you split vertically, especially if I work in
 small terminals.
I would prefere a horizontal split, thats why I changed it to the way
to the way it is
handled in the svn.vim commit case:

below new

> +    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>"

Why changing directory? I had to remove the cd .. to make it work. Otherwise
git diff couldn't find the repository.

Greetings,
  Peter

^ permalink raw reply

* Re: VCS comparison table
From: Andreas Ericsson @ 2006-10-17  8:16 UTC (permalink / raw)
  To: Aaron Bentley; +Cc: Jakub Narebski, bazaar-ng, git
In-Reply-To: <45346290.6050300@utoronto.ca>

Aaron Bentley wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Jakub Narebski wrote:
>> Well, <ref>~<n> means <n>-th _parent_ of a given ref, which for branches
>> (which constantly change) is a moving target.
> 
> Ah.  Bazaar uses negative numbers to refer to <n>th parents, and
> positive numbers to refer to the number of commits that have been made
> since the branch was initialized.
> 

What do you do once a branch has been thrown away, or has had 20 other 
branches merged into it? Does the offset-number change for the revision 
then, or do you track branch-points explicitly?

>> 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.
> 
> Sure.  Our UI approach is that unique identifiers can usefully be
> abstracted away with a combination of URL + number, in the vast majority
> of cases.
> 
>> 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.
> 
> The nice thing about revision numbers is that they're implicit-- no one
> needs to take any action to update them, and so you can always use them.
> 
>> 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.
> 
> If I understand correctly, in Bazaar, you'd just merge the current work
> into 'xx/topic'.
> 

merge != rebase though, although they are indeed similar. Let's take the 
example of a 'master' branch and topic branch topicA. If you rebase 
topicA onto 'master', development will appear to have been serial. If 
you instead merge them, it will either register as a real merge or, if 
the branch tip of 'master' is the branch start-point of topicA, it will 
result in a "fast-forward" where 'master' is just updated to the 
branch-tip of 'topicA'.

>> 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.
> 
> I'm not sure what you mean about divergence.  For example, Bazaar
> records the complete ancestry of each branch, and determining the point
> of divergence is as simple as finding the last common ancestor.  But are
> you considering only the initial divergence?  Or if the branches merge
> and then diverge again, would you consider that the point of divergence?
> 
> merge-point tracking is a prerequisite for Smart Merge, which does
> appear on our matrix.
> 
>> 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.
> 
> I'm not sure what you mean by API, unless you mean the commandline.  If
> that's what you mean, surely all unix commands are extensible in that
> regard.
> 

I'm fairly certain he's talking about the API in the sense it's being 
talked about in every other application. Extensive work has been made to 
libify a lot of the git code, which means that most git commands are 
made up of less than 400 lines of C code, where roughly 80% of the code 
is command-specific (i.e., argument parsing and presentation).

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

^ permalink raw reply

* Re: VCS comparison table
From: Andreas Ericsson @ 2006-10-17  7:50 UTC (permalink / raw)
  To: Aaron Bentley; +Cc: Linus Torvalds, Jakub Narebski, bazaar-ng, git
In-Reply-To: <45345AEF.6070107@utoronto.ca>

Aaron Bentley wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Linus Torvalds wrote:
>> 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.
> 
>> 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?
> 
> Right.  That's why I said all revisions can be named by a URL + a
> number, because it's the combination of the URL + a number that is
> unique.  (In bzr, each branch has a URL.)
> 

The revision will change between different repos though, so 
random-contributor A that doesn't have his repo publicised needs to send 
patches and can't log his exact problem revision somewhere, which makes 
it hard for random contributor B that runs into a similar problem but on 
a different project sometime later to find the offending code. I prefer 
the git way, but I'm a git user and probably biased.

That said, it shouldn't be impossible to add fixed, user-friendly 
bazaar-like revision numbers for git. We just have to reverse the
<committish>[^~]<number> syntax to also accept <committish>+<number>.

This would work marvelously with serial development but breaks horribly 
with merges unless the first (or last) commit on each new branch gets 
given a tag or some such.

Either way, I'm fairly certain both bazaar and git needs to distribute 
information to the user in need of finding the revision (which url and 
which number vs which sha). I also imagine that the bazaar users, just 
like the git users, are sufficiently apt copy-paste people to never 
actually read the prerequisite information.

> 
>> 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.
> 
> When two people have copies of the same revision, it's usually because
> they are each pulling from a common branch, and so the revision in that
> branch can be named.  Bazaar does use unique ids internally, but it's
> extremely rare that the user needs to use them.
> 

Well, if two people have the same revision in git, you *know* they have 
pulled from each other, because ALL objects are immutable. The point of 
"naming" the revision is moot, because it's something all SCM's can do.


>> 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.
> 
> But tags have local meaning only, unless someone has access to your
> repository, right?
> 

I imagine the bazaar-names with url+number only has local meaning unless 
someone has access to your repository too. One of the great benefits of 
git is that each revision is *always exactly the same* no matter in 
which repository it appears. This includes file-content, filesystem 
layout and, last but also most important, history.


>>>> 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.
> 
> The key thing about a checkout is that it's stored in a different
> location from its repository.  This provides a few benefits:
> 
> - - you can publish a repository without publishing its working tree,
>   possibly using standard mirroring tools like rsync.
> 

Can't all scm's do this?

> - - you can have working trees on local systems while having the
>   repository on a remote system.  This makes it easy to work on one
>   logical branch from multiple locations, without getting out of sync.
> 

This I'm not so sure about. Anyone wanna fill out how shallow clones and 
all that jazz works?

> - - you can use a checkout to maintain a local mirror of a read-only
>   branch (I do this with http://bazaar-vcs.com/bzr/bzr.dev).
> 

Check. Well, actually, you just clone it as usual but with the --bare 
argument and it won't write out the working tree files.

>> 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.
> 
> You can operate that way in bzr too, but I find it nicer to have one
> checkout for each active branch, plus a checkout of bzr.dev.  Our switch
> command also rewrites only the changed part of the working tree.
> 

Works in git as well, but each "checkout" (actually, locally referenced 
repository clone) gets a separate branch/tag namespace.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox