git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Stephen Leake <stephen_leake@stephe-leake.org>
Cc: git@vger.kernel.org
Subject: Re: Determining update/merge/current state of a workspace
Date: Sun, 2 Feb 2014 17:44:54 -0500	[thread overview]
Message-ID: <20140202224453.GA16196@sigill.intra.peff.net> (raw)
In-Reply-To: <85ppn540wi.fsf@stephe-leake.org>

On Sun, Feb 02, 2014 at 04:15:09PM -0600, Stephen Leake wrote:

> I always do 'fetch' and 'merge' separately, never 'pull'. So after a
> 'fetch', the DVC Emacs front end must determine what needs to happen
> next. I think there are three cases:

Doing the two steps separately is common in git, too. The cases you
mention are also something people commonly care about. Both "git
checkout" and "git status" will print out the relationship between the
current branch and its "upstream". These are sometimes referred to as
ahead/behind messages in the manual (because they are of the form "You
are N commits ahead of origin/master", etc).

> 3) fetch retrieved revisions, and there were local commits since
>    the previous fetch.
> 
>    There are two heads for the branch (the two described above), they
>    need to be merged, then the workspace updated.
> 
> I'm not sure how 'git fetch' handles case 3); I have not tested that
> case yet.

Git's fetch does not have to care about this case. It is responsible
only for updating the ref that keeps track of the remote side (e.g.,
refs/remotes/origin/master). Unlike in some other DVCSs, there is no
global concept of a "branch" in git. The ref "refs/heads/master" refers
to your local branch named "master", and the ref "refs/remotes/origin/master"
refers to some remote's branch with the same name. You can reconcile
them whenever and however you like, and do not have to do so immediately
(or at all).

> The question I have is:
> 
> What git queries can I run to determine which of the three states the
> current workspace is in?

If you want to know the relationship between two (or more) commits, you
can use `git rev-list` to enumerate them. You can use the symmetric
difference operator ("...") to walk both sides down to their merge-base.
The `--left-right` option will label them according to which side each
commit comes from. So try:

  git rev-list --left-right @{upstream}...HEAD

to see the commits, or just:

  git rev-list --left-right --count @{upstream}...HEAD

to just get the counts on each side. Note that I used "@{upstream}"
there instead of naming the branch specifically. The default remote
branch with which a local branch will merge can be configured, and does
not have to have the same name (or even be a remote branch).

> But to distinguish among the cases, I need to determine if one of these
> two revs is a child of the other or not. I don't see a git query to
> determine that directly.

I think what I gave above matches what you are looking for most
directly. But as you may have already guessed, you can also use rev-list
to find whether one rev is a child of the other (e.g., "git rev-list
--count a..b" != 0).

> I could try parsing a 'log' output; I have not investigated that.

Don't do that. As you might expect, `git log` is built on top of the
traversals done by `rev-list`. The latter is preferred as a building
block, because it is "plumbing" whose output is guaranteed not to change
in later git versions.

I hope that helps,

-Peff

  reply	other threads:[~2014-02-02 22:45 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-02 22:15 Determining update/merge/current state of a workspace Stephen Leake
2014-02-02 22:44 ` Jeff King [this message]
2014-02-02 23:04 ` David Aguilar
2014-02-03  0:50   ` brian m. carlson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140202224453.GA16196@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    --cc=stephen_leake@stephe-leake.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).