git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: Upcoming memcached releases + rambling.
@ 2008-02-10  9:47 George Spelvin
  2008-02-11 12:50 ` Jakub Narebski
  0 siblings, 1 reply; 6+ messages in thread
From: George Spelvin @ 2008-02-10  9:47 UTC (permalink / raw)
  To: git, memcached

A few notes about git that may be causing confusion:

1) "git pull" does more than you think, and is for developers only.

   To just follow some other work, use only "git fetch".

   "git pull" does a fetch, and then merges the fetched branch into your
   current HEAD.  If your current HEAD is a copy of the remote branch,
   this will be harmless, but if it's not, it will produce code changes.

   "git fetch" will fetch the remote branch, and then do a "fast-forward"
   update of the corresponding local tracking branch.  If the local
   tracking branch is not an ancestor of the fetched branch, it will
   abort with an error.

   So, in summary, don't use "pull" unless you want to do a merge.
   It will suppress the merge in the obvious trivial cases (no changes
   on one side or the other), but will happily combine things.

   (The reason that "pull" is such a prominent command is that it's what
   Linus does all day: merges other people's development into his tree.)


2) "git log old..new" is a special case of a very general mechanism
   for specifying a set of commits to examine.  See the man page for
   "git-rev-parse" for the full complete rules.  You specify a set of
   commits to include, and a set to exclude.

   The syntax is "include1 include2 ^exclude1 ^exclude2 include3...".

   A commit is included in the final set if it is an ancestor of one of
   the explicitly listed "include" commits, *and* it is *not* an ancestor
   of any of the listed "exclude" commits.

   old..new is a convenient equivalent for "^old new": everything in new's
   history that is not included in old's history.  Thus, "old1..new1
   old2..new2" is exactly synonymous with "old1..new2 old2..new1".
   They both mean that new1, new2, and all their ancestors are included,
   except that old1, old2, and all their ancestors are excluded.

   There is one magic bit of syntax, the symmetric difference operator
   "rev1...rev2" (note three dots).  That means all ancestors of rev1,
   and all ancestors of rev2, but excluding all common ancestors of both.
   It's also equivalent to an include-exclude list, but the computation
   of the exclude set is a bit more complicated.  (It's usually just
   one common ancestor, but there can be multiples in nasty criss-cross
   merge cases.)

3) "git diff old..new" uses the same syntax for a different purpose.
   diff only works with two commits, so that's simply an alias for
   "git diff old new".  (Whether this is a useful conveience or is too
   misleading for the beginner has been the subject of heated discussion
   on the git mailing list.)

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Upcoming memcached releases + rambling.
       [not found]         ` <5222C3B4-5E2C-45D2-8DF3-A85D69DDA2CF@spy.net>
@ 2008-02-10 11:05           ` Jeff King
  2008-02-10 15:14             ` Jakub Narebski
       [not found]           ` <47AD643D.3040800@rydia.net>
  1 sibling, 1 reply; 6+ messages in thread
From: Jeff King @ 2008-02-10 11:05 UTC (permalink / raw)
  To: Dustin Sallings; +Cc: dormando, memcached list, git

[I'm not on the list, so please cc me in replies]

On Fri, Feb 08, 2008 at 09:21:16PM -0800, Dustin Sallings wrote:

> I've seen lots of people using git for their own work, but not enough
> using it in a distributed fashion.  I've been asking questions about how
> to collaborate with git, but I can't seem to find any git experts who will
> answer questions.

Please, if you have git questions, feel free to ask them on the git list
(which I am cc'ing here).

> serve, bundle, export, import, incoming, and outgoing don't seem
> to have equivalences in git.

I don't know hg well at all, but I will attempt to translate (please
correct me if I'm wrong on any hg behavior).

"hg serve" runs a web repo browser and a pull server. In git, these
duties are split. Depending on what you want, you can:
  - for allowing people to pull from you, you can use git-daemon
  - for repository browsing, run an instance of gitweb. There is a
    git-instaweb script for doing one-off "I just need to set this up
    for a minute" versions.
  - you can also allow people to pull via http; just copy your '.git'
    directory somewhere that is accessible by the web server
  - you can also allow people to pull via ssh; just give them an ssh
    account and point them to host:/path/to/repo

"hg bundle" has an equivalent in git: "git bundle"

"hg export" seems to generate the commit message + patch for a set of
commits. The git equivalent is "git format-patch" which puts each patch
in its own mbox file (you can also use "git format-patch --stdout >mbox"
to put them all in one mbox.

"hg import" presumably applies the results of "hg export". In git, this
is "git am" (where am stands for apply mailbox), which applies the
changes from an entire mbox one by one.

"incoming" and "outgoing" seem to basically be diffs against remote
repositories (i.e., "what do I have that he doesn't" and vice versa). In
git, you would do a "git fetch" to say "contact the remote repository
and get what he has, but don't update any of my branches" followed by
"git log origin..HEAD" (what does I have that he doesn't) or "git log
HEAD..origin" (the opposite). You can also use the symmetric difference
with a graphical browser like gitk: "gitk origin...HEAD" which will show
everything that he has and everything you have, down to the point where
the two histories last diverged.

> 	I've contributed changes to both git and hg projects and haven't had  
> good luck submitting changes upstream.   I'd be interesting in talking to 
> people who collaborate on projects using git both as first and  
> second-level contributors to see if their experiences are any better than 
> mine.  I don't doubt that I may be doing it wrong.

Again, if you have specific questions, please feel free to ask on the
git list. We are more than happy to help out if we can.

> 	Should memcached choose git, it may be as simple as putting up a page  
> that says, ``this is how you clone, this is how you work, this is how you 
> submit your changes back.''

I don't know hg very well, but my impression is that the implementation
is quite similar to git and that writing a document "translating"
commands from one system to the other would be feasible.

-Peff

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Upcoming memcached releases + rambling.
       [not found]           ` <47AD643D.3040800@rydia.net>
@ 2008-02-10 11:15             ` Jeff King
  0 siblings, 0 replies; 6+ messages in thread
From: Jeff King @ 2008-02-10 11:15 UTC (permalink / raw)
  To: dormando; +Cc: Dustin Sallings, memcached list, git

On Sat, Feb 09, 2008 at 12:28:45AM -0800, dormando wrote:

> If I _think_ I understand these right, you can actually sometimes git
> diff with the second repo as an argument. That'll show the differences
> since the target repo/branch (git diff . /path/to/other/repo#branch),
> which will be incoming or outgoing.

No, that doesn't work. It will literally diff the two directories.

What you have probably seen is:

  git diff origin HEAD

which means "diff my current branch with the branch origin". Now
"origin" is typically the name of your upstream remote. However, we also
use the same name to store "tracking branches" that keep tabs on the
remote's state. So the branch "origin" stores the state of the remote's
current branch (as of the last time you did a "git fetch" of course).

But "git diff HEAD <someURL>" does not work. You would want "git fetch
<someURL> && git diff HEAD FETCH_HEAD".

> That'll show the raw changes... for showing the difference in changeset,
>   you can do a: git log --since HEAD origin
> ... if origin were the remote repo. If you don't have the latest
> changes, fetch more, rebase your repo on top of that, then git log
> --since will show you what you have to upload.

That --since is not necessary. You want "git log HEAD..origin" (where
"A..B" means "what's in B, but not in A"). "--since" is for
date-limiting, and the syntax is like "--since=2.weeks.ago".

> I think my knowledge on how to do this in git is a bit dated, so I'll go
> read (I started with git in 0.99 series, where it was missing most of
> these fancy "usability features", so sometimes I do things the hard way
> still).

Pre-1.5 and 1.5 have quite a few interface differences (and of course
there were many changes from 0.99 to 1.5 :) ).

> Otherwise you can use git fetch to "pull" the remote changes into a
> branch but not apply anywhere, then use git log with relative commit ids
> to show the changesets (with -p to show the full changes!)

Yes, although I would say that git fetch "fetches" changes, so as not to
confuse it with the "pull" command which does something different.

> Unless I'm getting my wires crossed and this is a patch management
> thinger, in that case it's 'git format-patch' and 'git am' (although
> there's an alternative to am).

Actually "am" is the new alternative to "applymbox" which is now
officially gone in 1.5.4.

-Peff

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Upcoming memcached releases + rambling.
  2008-02-10 11:05           ` Upcoming memcached releases + rambling Jeff King
@ 2008-02-10 15:14             ` Jakub Narebski
  2008-02-10 15:39               ` Jakub Narebski
  0 siblings, 1 reply; 6+ messages in thread
From: Jakub Narebski @ 2008-02-10 15:14 UTC (permalink / raw)
  To: Jeff King; +Cc: Dustin Sallings, dormando, memcached list, git

Jeff King <peff@peff.net> writes:

> [I'm not on the list, so please cc me in replies]
> 
> On Fri, Feb 08, 2008 at 09:21:16PM -0800, Dustin Sallings wrote:
> 
> > I've seen lots of people using git for their own work, but not enough
> > using it in a distributed fashion.  I've been asking questions about how
> > to collaborate with git, but I can't seem to find any git experts who will
> > answer questions.
> 
> Please, if you have git questions, feel free to ask them on the git list
> (which I am cc'ing here).

Did they at least asked (tried to ask) on #git channel on FreeNode?
 
> > serve, bundle, export, import, incoming, and outgoing don't seem
> > to have equivalences in git.
> 
> I don't know hg well at all, but I will attempt to translate (please
> correct me if I'm wrong on any hg behavior).

I have tried to follow hg(1), from
  http://www.selenic.com/mercurial/hg.1.html

> "hg serve" runs a web repo browser and a pull server. In git, these
> duties are split. Depending on what you want, you can:
>   - for allowing people to pull from you, you can use git-daemon
>   - for repository browsing, run an instance of gitweb. There is a
>     git-instaweb script for doing one-off "I just need to set this up
>     for a minute" versions.

Or you can use one of the history viewers: gitk (Tcl/Tk), qgit (Qt),
Giggle or GitView (GTK+), or tig (ncurses).

>   - you can also allow people to pull via http; just copy your '.git'
>     directory somewhere that is accessible by the web server

Note that you have to run git-update-server-info to update auxiliary
info file to help dumb servers (which includes HTTP server),
preferably in 'update' (for publishing repos) or 'post-commit' (for
working repos) hook.

>   - you can also allow people to pull via ssh; just give them an ssh
>     account and point them to host:/path/to/repo

You can use git-shell as shell to lomit access to only pulling /
pushing changes.

IMHO it is better to leave serving web pages to web server, instead of
trying to do that in an SCM... even if Python has support for creating
basic HTTP server easily. (We could add bare-bones gitweb and git
only, written in Perl HTTP server in gitweb/, but what for...).


> "hg bundle" has an equivalent in git: "git bundle"

Minor difference: it is "git bundle create" and "git bundle unbundle"
(or "git pull <bundle>") versus "hg bundle" and "hg unbundle".

> "hg export" seems to generate the commit message + patch for a set of
> commits. The git equivalent is "git format-patch" which puts each patch
> in its own mbox file (you can also use "git format-patch --stdout >mbox"
> to put them all in one mbox.

It looks like there is no exact equivalent. "git format-patch" is used
to generate series of patches, but it doesn't for example saves
parent(s) of a commit; not that it makes much sense. It is meant to
send patches for review (and then applying).

By the way, for binary files git would send binary diff, which can be
applied _only_ if you have exact preimage, so this is no problem:

hg export:

    Without the -a option, export will avoid generating diffs of files
    it detects as binary. With -a, export will generate a diff anyway,
    probably with undesirable results.

> "hg import" presumably applies the results of "hg export". In git, this
> is "git am" (where am stands for apply mailbox), which applies the
> changes from an entire mbox one by one.

Note that "git format-patch" / "git am" is meant for mail driven
workflow, with patches send for _review_ to maintainer or [public]
mailing list, and applied by maintainer on case by case basis. This
means for example that commit from patch might be applied in different
place of revision graph than original; "git am --3way" fallbacks on
3-way merge (based on embedded original pre-image blob (file)
identifier) if patch cannot be applied cleanly.

It is not meant as a transport mechanism: use interactive protocols
(ssh, git, http) for that, or git-bundle if it is impossible.

> "incoming" and "outgoing" seem to basically be diffs against remote
> repositories (i.e., "what do I have that he doesn't" and vice versa). In
> git, you would do a "git fetch" to say "contact the remote repository
> and get what he has, but don't update any of my branches" followed by
> "git log origin..HEAD" (what does I have that he doesn't) or "git log
> HEAD..origin" (the opposite). You can also use the symmetric difference
> with a graphical browser like gitk: "gitk origin...HEAD" which will show
> everything that he has and everything you have, down to the point where
> the two histories last diverged.

Here (and in neighbour post about diff between branches) we come to
the main difference between Git and Mercurial, namely that Git uses
multiple-branches in repository workflow extensively[*1*], while in
Mercurial multiple branches in single repository are still (from what
I have read) secondary citizens; main workflow is still one branch per
repository.

(I'm not sure if Mercurial gets correctly the difference between tags
and branches, but that is just me spreading FUD ;-)).

Git uses concept of remote tracking branches to track changes in
remote repository. By default after cloning repository which has for
example branches 'master' (stable branch) and 'next' (development
branch) you have local branch 'master' (fullname: refs/heads/master)
for your own work, and 'origin/master' and 'origin/next' (where
'origin' is default name for origin-al repository you by default fetch
from) remote tracking branches (fullname: refs/remotes/origin/master,
refs/remotes/origin/next). You have also symbolic ref 'HEAD' which
denotes current branch; points which branch you are currently work
with, and ref 'origin' (fullname: refs/remotes/origin/HEAD) denoting
default branch on remote repository.

In Git "pull" consists of two steps: 'fetch' which downloads objects
(changes) and updates refs, and 'merge' which joins the histories (or
does fast-forward) and updates current branch. From what I understand
from Mercurial documentation hg it has those actions split in a
different way: "hg incoming" to examine changes, and "hg pull;
hg update" to join histories.

So to examine some defined repository one would do a "git fetch <repo>", 
where <repo> is shortcut repository name, and then examine
<repo>/<branch> remote tracking branches. Note that it looks like
"hg incoming" can deal sensibly only with one branch per repository
repositories (further FUD spreading ;-)). If you want to preview some
foreign repo you can use "git fetch <URL>" or "git fetch <URL>
<branch>" and examine FETCH_HEAD.

Note that the fact that some branch in remote repository and
respective remote-tracking branch differ might mean many things:
 a.) remote repository has avanced wrt. our repository
 b.) remote repository lags behind our repository
     (e.g. both are sister repositories cloned from the same repo)
 c.) histories diverged, or were rewound / rewritten
I wonder how Mercurial deals with cases b.) and c.) (further anti-hg
FUD ;-))

Now to examine what changed you can use _generic_ revision list
specification in some history browser (git-log, gitk, git-show-branch,
etc.). Here you can use "A..B" syntax (what's in B, excluding what is
in A, which in the case of linear history is: what is between A and
B), and "A...B" syntax (what's in A and B, excluding what's in common
ancestor (merge base) of both of them). A and/or B can be: HEAD
(current branch), 'origin' or <repo> for default remote repository
branch, FETCH_HEAD for what was just fetched, or even
origin@{1}..origin to show what fetch brought to 'origin/HEAD'.

If Git ever would want to have a command which would show which
branches differ in some remote repository, I think it would be added
to "git remote" (which I recommend checking).

> > 	I've contributed changes to both git and hg projects and haven't had  
> > good luck submitting changes upstream.   I'd be interesting in talking to 
> > people who collaborate on projects using git both as first and  
> > second-level contributors to see if their experiences are any better than 
> > mine.  I don't doubt that I may be doing it wrong.
> 
> Again, if you have specific questions, please feel free to ask on the
> git list. We are more than happy to help out if we can.

Well, there are around 250 contributors to git which have more than
one commit to his/her name. Even excluding some fuzz factor due to
wrong / changed credentials.

Masukomi (Kate Rhodes) wrote in her blog in "Some thoughts about Git"
http://weblog.masukomi.org/2008/2/4/some-thoughts-about-git

  And then I joined the Git mailing list. Linus mentioned that it had
  a high signal to noise ratio but... *holy shit*. I have been on a
  lot of mailing lists for open source projects over the years and I
  have never seen anything like this. Almost every e-mail is a patch,
  or a good discussion of a patch, or a good discussion of some new
  feature and how to go about implementing it.

> > 	Should memcached choose git, it may be as simple as putting up a page  
> > that says, ``this is how you clone, this is how you work, this is how you 
> > submit your changes back.''
> 
> I don't know hg very well, but my impression is that the implementation
> is quite similar to git and that writing a document "translating"
> commands from one system to the other would be feasible.

Actualy while ideas and workflows might be similar, implementation
differs quite a bit.

Git is snapshot based[*2*]; in git repository is object database, with
commits being points in DAG (Directed Acyclic Graph) of revisions,
pointing to their parent commits and to snapshot of a repository state
at given revision. Branches, remote tracking branches and tags are
[named] pointers to points (staring points) in DAG of revisions. There
HEAD which is pointer to pointer, or simply something which names
current branch (symbolic reference to current branch name). File
structure is reflected in object database using hierchical tree object
structure; file name and parts of permissions are stored in tree
objects. This structure allows for fast merges (and fast warm-cache
performance, supposedly).

Mercurial I know only secondhand, from the discussion on #revctrl IRC
channel, and from Mercurial documentation. It is AFAICT
changeset-based, with changesets stored "hashed" in per [current]
filename buckeds, tied together in flat manifest like file which ties
files together, tied together in revlog changeset-log file which
stores commits. Branches and tags are stored as in-tree file (inside
working directory of repository), similarly to .gitignore / .hgignore
file, with (for tags at least) some complicated rule of updating it
when switching branches and going to given revision (further anti-hg
FUD; I hope that changed...). The pref-file-bucket structure allows
for fast patch applying (and fast cold-cache performance, supposedly).


Footnotes:
==========
[*1*] Junio C Hamano (current git maintainer), wrote in his blog
in "FLOSS weekly #19 follow-up (3)" entry:
  http://gitster.livejournal.com/9970.html 

  "The very basic structure and idea behind git has not changed since
   Linus wrote the initial implementation".

  Well, while that is not _untrue_, that statement itself may lead to
  confusion unless clarified.

  [...]

  * We did not envision that multiple branches in a single repository
    would turn out to be such a useful way to work, and did not have
    support for switching branches;


[*2*] Even if in packed form it is stored as delta chains; but that is
      just [transparent] engine.

-- 
Jakub Narebski
Poland
ShadeHawk on #git

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Upcoming memcached releases + rambling.
  2008-02-10 15:14             ` Jakub Narebski
@ 2008-02-10 15:39               ` Jakub Narebski
  0 siblings, 0 replies; 6+ messages in thread
From: Jakub Narebski @ 2008-02-10 15:39 UTC (permalink / raw)
  To: git; +Cc: memcached, mercurial

[I hate subscribe-only default-DROP mailing lists for a OSS project,
 where you don't get even: waiting for moderator approval for not
 subscribed. I'm trying to resend it via GMane. I'm not subscribed
 to memcached mailing list]

Jeff King <peff@peff.net> writes:

> [I'm not on the list, so please cc me in replies]
> 
> On Fri, Feb 08, 2008 at 09:21:16PM -0800, Dustin Sallings wrote:
> 
> > I've seen lots of people using git for their own work, but not enough
> > using it in a distributed fashion.  I've been asking questions about how
> > to collaborate with git, but I can't seem to find any git experts who will
> > answer questions.
> 
> Please, if you have git questions, feel free to ask them on the git list
> (which I am cc'ing here).

Did they at least asked (tried to ask) on #git channel on FreeNode?
 
> > serve, bundle, export, import, incoming, and outgoing don't seem
> > to have equivalences in git.

> I don't know hg well at all, but I will attempt to translate (please
> correct me if I'm wrong on any hg behavior).

I have tried to follow hg(1), from
  http://www.selenic.com/mercurial/hg.1.html

> "hg serve" runs a web repo browser and a pull server. In git, these
> duties are split. Depending on what you want, you can:
>   - for allowing people to pull from you, you can use git-daemon
>   - for repository browsing, run an instance of gitweb. There is a
>     git-instaweb script for doing one-off "I just need to set this up
>     for a minute" versions.

Or you can use one of the history viewers: gitk (Tcl/Tk), qgit (Qt),
Giggle or GitView (GTK+), or tig (ncurses).

>   - you can also allow people to pull via http; just copy your '.git'
>     directory somewhere that is accessible by the web server

Note that you have to run git-update-server-info to update auxiliary
info file to help dumb servers (which includes HTTP server),
preferably in 'update' (for publishing repos) or 'post-commit' (for
working repos) hook.

>   - you can also allow people to pull via ssh; just give them an ssh
>     account and point them to host:/path/to/repo

You can use git-shell as shell to lomit access to only pulling /
pushing changes.

IMHO it is better to leave serving web pages to web server, instead of
trying to do that in an SCM... even if Python has support for creating
basic HTTP server easily. (We could add bare-bones gitweb and git
only, written in Perl HTTP server in gitweb/, but what for...).


> "hg bundle" has an equivalent in git: "git bundle"

Minor difference: it is "git bundle create" and "git bundle unbundle"
(or "git pull <bundle>") versus "hg bundle" and "hg unbundle".

> "hg export" seems to generate the commit message + patch for a set of
> commits. The git equivalent is "git format-patch" which puts each patch
> in its own mbox file (you can also use "git format-patch --stdout >mbox"
> to put them all in one mbox.

It looks like there is no exact equivalent. "git format-patch" is used
to generate series of patches, but it doesn't for example saves
parent(s) of a commit; not that it makes much sense. It is meant to
send patches for review (and then applying).

By the way, for binary files git would send binary diff, which can be
applied _only_ if you have exact preimage, so this is no problem:

hg export:

    Without the -a option, export will avoid generating diffs of files
    it detects as binary. With -a, export will generate a diff anyway,
    probably with undesirable results.

> "hg import" presumably applies the results of "hg export". In git, this
> is "git am" (where am stands for apply mailbox), which applies the
> changes from an entire mbox one by one.

Note that "git format-patch" / "git am" is meant for mail driven
workflow, with patches send for _review_ to maintainer or [public]
mailing list, and applied by maintainer on case by case basis. This
means for example that commit from patch might be applied in different
place of revision graph than original; "git am --3way" fallbacks on
3-way merge (based on embedded original pre-image blob (file)
identifier) if patch cannot be applied cleanly.

It is not meant as a transport mechanism: use interactive protocols
(ssh, git, http) for that, or git-bundle if it is impossible.

> "incoming" and "outgoing" seem to basically be diffs against remote
> repositories (i.e., "what do I have that he doesn't" and vice versa). In
> git, you would do a "git fetch" to say "contact the remote repository
> and get what he has, but don't update any of my branches" followed by
> "git log origin..HEAD" (what does I have that he doesn't) or "git log
> HEAD..origin" (the opposite). You can also use the symmetric difference
> with a graphical browser like gitk: "gitk origin...HEAD" which will show
> everything that he has and everything you have, down to the point where
> the two histories last diverged.

Here (and in neighbour post about diff between branches) we come to
the main difference between Git and Mercurial, namely that Git uses
multiple-branches in repository workflow extensively[*1*], while in
Mercurial multiple branches in single repository are still (from what
I have read) secondary citizens; main workflow is still one branch per
repository.

(I'm not sure if Mercurial gets correctly the difference between tags
and branches, but that is just me spreading FUD ;-)).

Git uses concept of remote tracking branches to track changes in
remote repository. By default after cloning repository which has for
example branches 'master' (stable branch) and 'next' (development
branch) you have local branch 'master' (fullname: refs/heads/master)
for your own work, and 'origin/master' and 'origin/next' (where
'origin' is default name for origin-al repository you by default fetch
from) remote tracking branches (fullname: refs/remotes/origin/master,
refs/remotes/origin/next). You have also symbolic ref 'HEAD' which
denotes current branch; points which branch you are currently work
with, and ref 'origin' (fullname: refs/remotes/origin/HEAD) denoting
default branch on remote repository.

In Git "pull" consists of two steps: 'fetch' which downloads objects
(changes) and updates refs, and 'merge' which joins the histories (or
does fast-forward) and updates current branch. From what I understand
from Mercurial documentation hg it has those actions split in a
different way: "hg incoming" to examine changes, and "hg pull;
hg update" to join histories.

So to examine some defined repository one would do a "git fetch <repo>", 
where <repo> is shortcut repository name, and then examine
<repo>/<branch> remote tracking branches. Note that it looks like
"hg incoming" can deal sensibly only with one branch per repository
repositories (further FUD spreading ;-)). If you want to preview some
foreign repo you can use "git fetch <URL>" or "git fetch <URL>
<branch>" and examine FETCH_HEAD.

Note that the fact that some branch in remote repository and
respective remote-tracking branch differ might mean many things:
 a.) remote repository has avanced wrt. our repository
 b.) remote repository lags behind our repository
     (e.g. both are sister repositories cloned from the same repo)
 c.) histories diverged, or were rewound / rewritten
I wonder how Mercurial deals with cases b.) and c.) (further anti-hg
FUD ;-))

Now to examine what changed you can use _generic_ revision list
specification in some history browser (git-log, gitk, git-show-branch,
etc.). Here you can use "A..B" syntax (what's in B, excluding what is
in A, which in the case of linear history is: what is between A and
B), and "A...B" syntax (what's in A and B, excluding what's in common
ancestor (merge base) of both of them). A and/or B can be: HEAD
(current branch), 'origin' or <repo> for default remote repository
branch, FETCH_HEAD for what was just fetched, or even
origin@{1}..origin to show what fetch brought to 'origin/HEAD'.

If Git ever would want to have a command which would show which
branches differ in some remote repository, I think it would be added
to "git remote" (which I recommend checking).

> >     I've contributed changes to both git and hg projects and haven't had  
> > good luck submitting changes upstream.   I'd be interesting in talking to 
> > people who collaborate on projects using git both as first and  
> > second-level contributors to see if their experiences are any better than 
> > mine.  I don't doubt that I may be doing it wrong.
> 
> Again, if you have specific questions, please feel free to ask on the
> git list. We are more than happy to help out if we can.

Well, there are around 250 contributors to git which have more than
one commit to his/her name. Even excluding some fuzz factor due to
wrong / changed credentials.

Masukomi (Kate Rhodes) wrote in her blog in "Some thoughts about Git"
http://weblog.masukomi.org/2008/2/4/some-thoughts-about-git

  And then I joined the Git mailing list. Linus mentioned that it had
  a high signal to noise ratio but... *holy shit*. I have been on a
  lot of mailing lists for open source projects over the years and I
  have never seen anything like this. Almost every e-mail is a patch,
  or a good discussion of a patch, or a good discussion of some new
  feature and how to go about implementing it.

> >     Should memcached choose git, it may be as simple as putting up a page  
> > that says, ``this is how you clone, this is how you work, this is how you 
> > submit your changes back.''
> 
> I don't know hg very well, but my impression is that the implementation
> is quite similar to git and that writing a document "translating"
> commands from one system to the other would be feasible.

Actualy while ideas and workflows might be similar, implementation
differs quite a bit.

Git is snapshot based[*2*]; in git repository is object database, with
commits being points in DAG (Directed Acyclic Graph) of revisions,
pointing to their parent commits and to snapshot of a repository state
at given revision. Branches, remote tracking branches and tags are
[named] pointers to points (staring points) in DAG of revisions. There
HEAD which is pointer to pointer, or simply something which names
current branch (symbolic reference to current branch name). File
structure is reflected in object database using hierchical tree object
structure; file name and parts of permissions are stored in tree
objects. This structure allows for fast merges (and fast warm-cache
performance, supposedly).

Mercurial I know only secondhand, from the discussion on #revctrl IRC
channel, and from Mercurial documentation. It is AFAICT
changeset-based, with changesets stored "hashed" in per [current]
filename buckeds, tied together in flat manifest like file which ties
files together, tied together in revlog changeset-log file which
stores commits. Branches and tags are stored as in-tree file (inside
working directory of repository), similarly to .gitignore / .hgignore
file, with (for tags at least) some complicated rule of updating it
when switching branches and going to given revision (further anti-hg
FUD; I hope that changed...). The pref-file-bucket structure allows
for fast patch applying (and fast cold-cache performance, supposedly).


Footnotes:
==========
[*1*] Junio C Hamano (current git maintainer), wrote in his blog
in "FLOSS weekly #19 follow-up (3)" entry:
  http://gitster.livejournal.com/9970.html 

  "The very basic structure and idea behind git has not changed since
   Linus wrote the initial implementation".

  Well, while that is not _untrue_, that statement itself may lead to
  confusion unless clarified.

  [...]

  * We did not envision that multiple branches in a single repository
    would turn out to be such a useful way to work, and did not have
    support for switching branches;


[*2*] Even if in packed form it is stored as delta chains; but that is
      just [transparent] engine.

-- 
Jakub Narebski
Poland
ShadeHawk on #git

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Upcoming memcached releases + rambling.
  2008-02-10  9:47 George Spelvin
@ 2008-02-11 12:50 ` Jakub Narebski
  0 siblings, 0 replies; 6+ messages in thread
From: Jakub Narebski @ 2008-02-11 12:50 UTC (permalink / raw)
  To: memcached; +Cc: git

"George Spelvin" <linux@horizon.com> writes:

> A few notes about git that may be causing confusion:
> 
> 1) "git pull" does more than you think, and is for developers only.
> 
>    To just follow some other work, use only "git fetch".
> 
>    "git pull" does a fetch, and then merges the fetched branch into your
>    current HEAD.  If your current HEAD is a copy of the remote branch,
>    this will be harmless, but if it's not, it will produce code changes.

Note that "git fetch" usually fetches multiple branches; with default
configuration it fetches _all_ the branches. "git pull" would merge
the one marked for merge into current branch (HEAD is current branch),
either the one marked explicitely, or the first/main branch.
 
>    "git fetch" will fetch the remote branch, and then do a "fast-forward"
>    update of the corresponding local tracking branch.  If the local
>    tracking branch is not an ancestor of the fetched branch, it will
>    abort with an error.

But you can force fetching even if branch(es) in remote repository are
not ancestors of local tracking branches, which is needed if tracked
branch is rewound, reforked or rebased. Moreover by default this check
is disabled: all fetches are "forced".

You can always go to the previous value of branch thanks to reflogs,
so it is not really less safe, and avoids some hassle.

>    So, in summary, don't use "pull" unless you want to do a merge.
>    It will suppress the merge in the obvious trivial cases (no changes
>    on one side or the other), but will happily combine things.
> 
>    (The reason that "pull" is such a prominent command is that it's what
>    Linus does all day: merges other people's development into his tree.)

BTW. with newest git "git pull" _can_ rebase instead of merge.

> 2) "git log old..new" is a special case of a very general mechanism
>    for specifying a set of commits to examine.

>    The syntax is "include1 include2 ^exclude1 ^exclude2 include3...".

>    There is one magic bit of syntax, the symmetric difference operator
>    "rev1...rev2" (note three dots).  That means all ancestors of rev1,
>    and all ancestors of rev2, but excluding all common ancestors of both.
>    It's also equivalent to an include-exclude list, but the computation
>    of the exclude set is a bit more complicated.  (It's usually just
>    one common ancestor, but there can be multiples in nasty criss-cross
>    merge cases.)

"rev1...rev2" is equivalent to "rev1 rev2 --not $(git merge-base rev1 rev2)"
which I think explains what it does.
 
> 3) "git diff old..new" uses the same syntax for a different purpose.
>    diff only works with two commits, so that's simply an alias for
>    "git diff old new".  (Whether this is a useful conveience or is too
>    misleading for the beginner has been the subject of heated discussion
>    on the git mailing list.)

By the way, "git diff rev1...rev2" also works, and shows diff between
rev2 and common ancestor of rev1 and rev2 (merge base).

-- 
Jakub Narebski
Poland
ShadeHawk on #git

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2008-02-11 12:55 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <47AAC7DA.2010604@rydia.net>
     [not found] ` <4422C0B2-6874-41EA-B4A0-4F3414F385FC@spy.net>
     [not found]   ` <47AB3DBD.60004@rydia.net>
     [not found]     ` <3897B3FD-4DCB-4150-8A07-7F8868A70A93@spy.net>
     [not found]       ` <47AD2D1F.7030807@rydia.net>
     [not found]         ` <5222C3B4-5E2C-45D2-8DF3-A85D69DDA2CF@spy.net>
2008-02-10 11:05           ` Upcoming memcached releases + rambling Jeff King
2008-02-10 15:14             ` Jakub Narebski
2008-02-10 15:39               ` Jakub Narebski
     [not found]           ` <47AD643D.3040800@rydia.net>
2008-02-10 11:15             ` Jeff King
2008-02-10  9:47 George Spelvin
2008-02-11 12:50 ` Jakub Narebski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).