tags:

views:

381

answers:

4

ref^ refers to the commit before ref, what about getting the commit after ref?

For example, if I git checkout 12345 how do I check out the next commit?

Thanks.

PS Yes, git's a DAG node pointer struct tree whatever. How do I find the commit after this one?

+3  A: 

There is no unique "next commit". Because history in Git is a DAG, and not a line, many commits can have a common parent (branches), and commits can have more than one parent (merges).

If you have a particular branch in mind, you can look at its log and see what commit lists the present one as its parent.

Novelocrat
By that logic there's no "previous commit" either, but there's plenty of syntax for getting the parent(s).
Schwern
@Schwern: There is no "previous commit" either; `<rev>^` is "parent commit" ('first parent' for merge commits).
Jakub Narębski
+5  A: 

As illustrated by this thread, in a VCS based on history represented by a DAG (Directed Acyclic Graph), there is not "one parent" or "one child".

        C1 -> C2 -> C3
      /               \
A -> B                  E -> F
      \               /
        D1 -> D2 ----/

The ordering of commits is done by "topo-order" or "date-order" (see GitPro book)

But since Git1.6.0, you can list the children of a commit.

git rev-list --children
git log --children

Note: for parent commits, you have the same issue, with the suffix ^ to a revision parameter meaning the first parent of that commit object. ^<n> means the <n>th parent (i.e. rev^ is equivalent to rev^1).

If you are on branch foo and issue "git merge bar" then foo will be the first parent.
I.e: The first parent is the branch you were on when you merged, and the second is the commit on the branch that you merged in.

VonC
`git rev-list --children` sure looks like what I want, but it doesn't DWIM. It appears to list all the parents and their children. I suppose I can list them all and parse through them... bleh, but its something.
Schwern
@Schwern: true, `git rev-list --children` is not for listing just children, but for listing parents *with their children*... you always need to parse.
VonC
A: 

Each commit stores a pointer to its parent (parents, in case of merge(standard) commit).

So, there is no way to point to a child commit (if there is one) from the parent.

Lakshman Prasad
Commit cannot store pointers to its children, as additional child commits (branching points) can be added at later point.
Jakub Narębski
@Jakub I don't really follow. They can't be added later?
Schwern
Jakub: Thats exactly what I said. 'Each commit stores pointers only to its parent.'
Lakshman Prasad
@Schwern: Commits in git are immutable (which has nice consequence of accountability), so pointers to children cound't "be added later". One of the reasons is that identifier of commit (used e.g. in "parent" links) depends on the contents of the comit; this is the only solution in distributed system, without central numbering authority. Also "children" of commits depends on the branches you have, and this in turn can be different from repository to repository (and commits are the same in each repository).
Jakub Narębski
@becomingGuru: My comment was about why it is impossible to have pointers to child comits in the commit object.
Jakub Narębski
Jakub: Then why the downvote? (or so I thought.)
Lakshman Prasad
@becomingGuru I down voted it. It may be true, but it does not answer my question. The question is "how do I find the next commit in git?" It is not "does a git commit store a pointer to its children?"
Schwern
+1  A: 

If the child commits are all on some branch, you can use "gitk --all commit^..", where "commit" is something identifying the commit. For example, if the commit's abbreviated SHA-1 is c6661c5, then type "gitk --all c6661c5^.."

You will probably need to enter the full SHA-1 into gitk's "SHA1 ID:" cell. You will need the full SHA-1, which for this example can be obtained via "git rev-parse c6661c5"

Alternatively, "git rev-list --all --children | grep '^c6661c5883bb53d400ce160a5897610ecedbdc9d' will produce a line containing all the children of this commit, presumably whether or not there is a branch involved.