- Which commits are mine?
You need to define "mine". What does it mean for a commit to be "yours"?
Edit: you added under "mine" I mean the changes done in my local repository, including amended commits. First, always remember that commits are snapshots; to turn a snapshot into a change-set, you must pick some other commit and run git diff
to compare the two commits. The result of the comparison is a set of instructions for turning the first snapshot into the second snapshot. That's not necessarily something you, or even anyone, did: it's just a set of changes that produce the same result. (This is why sometimes git diff
says "delete the close brace of a previous block, plus most of this block" rather than "delete all of this block".)
Git isn't really about where a commit was made: if you connect two Git repositories, any commit with hash ID a1b2c3d
, for instance, in either repo is the same commit as a commit with hash ID a1b2c3d
in the other repo. What git push
and git fetch
do is connect two Git repositories, and transfer commits between them. A push operation means connect my repo to someone else's and attempt to give the someone-else some commits I have in my repo, which I assume they don't have yet. A fetch operation means connect my repo to someone else's repo and attempt to get commits they have, that I assume I don't have yet.
If you fetch from Alice's repository, then push to Bob's repository, this allows you to transfer commits that originally were only in Alice's repository, over to Bob's repository. So the fact that you gave Bob commit a1b2c3d
doesn't mean that commit a1b2c3d
is something you wrote yourself, it just means Bob didn't have a1b2c3d
—he had not yet obtained it directly from Alice, or from anyone else either.
Last, if you run git commit --amend
, that doesn't change any existing commit. Instead, it just makes a new (different, presumably better) commit whose parent is the same as the --amend
ed commit's parent:
...--o--o--0bad <-- branch
becomes:
0bad [abandoned]
/
...--o--o--1337 <-- branch
if the old commit's hash begins with 0bad
and the new one's begins with 1337
.
- Which commits are replaced ...
None. Commits are identified by hash IDs. Those hash IDs continue to identify the same commits.
However, we do know from the git push
output that the name reimplement
in the other Git used to represent the commit whose hash ID is 7b4eaa2
, and now represents the commit whose hash ID is 1295174
. This factors into your question 3:
- Which commits are gone from remote?
We also know two more things from your own git log
output:
The string 7b4eaa2...1295174
selects the four displayed commits. Since A...B
means "commits reachable from either A
or B
but not from both A
and B
", that means those four commits are reachable from one of those two commits, but not from both of them.
The output from git log --graph
is further restrained to occur in topological order:
Show no parents before all of its children are shown, and avoid showing commits on multiple lines of history intermixed.
Since 7b4eaa2
came out last, this means all of its children have been shown before that point. Since 1295174
came out first, it has no children. The intermediate commits must either be children of 7b4eaa2
(i.e., 7b4eaa2
is their parent or grandparent), or parents of 1295174
.
Putting these all together
We know that 1295174
is the new tip of reimplement
in the remote (since the push was accepted and it is the tip of reimplement
in your own repository):
... <-1295174 <-- reimplement
We know that the remote's old reimplement
, before the git push
, ended with:
... <-7b4eaa2
What we must consider is whether we should draw what is now in your own repository like this:
?--09630ef--0f477bf--1295174 <-- reimplement
\
7b4eaa2 [abandoned]
or like this:
?--1295174 <-- reimplement
\
09630ef--0f477bf--7b4eaa2 [abandoned]
or even like this:
?--09630ef--1295174 <-- reimplement
\
0f477bf--7b4eaa2 [abandoned]
Your git log 1295174...7b4eaa2
would show the first one as what we've seen. It would show the second, though, as:
* 1295174 (HEAD -> reimplement) TEMPORARY
* 7b4eaa2 TEMPORARY
* 09630ef Setup $DB::single
* 0f477bf Prettify code
and the third in yet another form. (If 1295174
were a merge commit with both 0f477bf
and 09630ef
as parents, we'd see yet a different graph output: we know for certain that all the commits shown here are linearly related or unrelated.) Hence, going back to Q3:
- Which commits are gone from remote?
we can say for certain that 7b4eaa2
is no longer reachable, in that Git, by the name reimplement
. The name reimplement
instead names 1295174
, and the parent of 1295174
is 0f477bf
and the parent of 0f477bf
is 09630ef
.
If 7b4eaa2
is completely unreachable by branch or tag or similar names in the remote Git, and the remote Git has no reflogs, and a garbage collection pass has completed, commit 7b4eaa2
will have been collected and removed.