3

When I do git push --force I see next output from git:

$ git push --force
Counting objects: 21, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (21/21), done.
Writing objects: 100% (21/21), 2.36 KiB | 1.18 MiB/s, done.
Total 21 (delta 14), reused 0 (delta 0)
To repo:/v1/repos/DB-Hooks
 + 7b4eaa2...1295174 reimplement -> reimplement (forced update)

$ git log --graph --decorate --pretty=oneline --abbrev-commit 7b4eaa2...1295174
* 1295174 (HEAD -> reimplement) TEMPORARY
* 0f477bf Prettify code
* 09630ef Setup $DB::single
* 7b4eaa2 TEMPORARY

How can I check what happened here from this log?

  1. Which commits are mine? (under "mine" I mean the changes done in my local repository, including amended commits)
  2. Which commits are replaced and what replaced in those commits?
  3. Which commits are gone from remote? (what changes I introduce in my local repository)

3 Answers 3

5
  1. 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 --amended 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.

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

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

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

1
  • I have updated my question to be more clear and round some useful options (see my answer). But I still do not find option which will show changes in not cherry-picked commits (see suggested output in that answer) Commented Jan 8, 2018 at 12:06
0

Try this:

To display last commit diff

git diff HEAD~1 

To display last commit modified files

git diff HEAD~1 --name-only
0

I have found these two options helpful to see what is comming on --left-right --cherry-pick --cherry-mark --boundary:

--left-right
Mark which side of a symmetric difference a commit is reachable from. Commits from the left side are prefixed with < and those from the right with >

--boudary I need it to show parent root

--cherry-pick
Omit any commit that introduces the same change as another commit on the “other side” when the set of commits are limited with symmetric difference.

$ git log --graph --decorate --pretty=oneline --abbrev-commit --left-right --cherry-pick --boundary 8cb6531...1295174
> 1295174 (HEAD -> reimplement) TEMPORARY
> 0f477bf Prettify code
> 09630ef Setup $DB::single
> 1e1b4a3 Wrap whole DB::DB into &dbcall by moving DB::db into DB::interact
| < 8cb6531 TEMPORARY
| < e348241 Wrap whole DB::DB into &dbcall by moving DB::db into DB::interact
|/  
o 6086d62 Code comment

Or with --cherry-mark we can see not touched commits:

$ git log --graph --decorate --pretty=oneline --abbrev-commit --left-right --cherry-mark --boundary 8cb6531...1295174
> 1295174 (HEAD -> reimplement) TEMPORARY
> 0f477bf Prettify code
> 09630ef Setup $DB::single
= 3e4cc19 Debugger debugging is finished. Remove mark
= 3df5e8c Fix doc
> 1e1b4a3 Wrap whole DB::DB into &dbcall by moving DB::db into DB::interact
| < 8cb6531 TEMPORARY
| = 5b1ce15 Debugger debugging is finished. Remove mark
| = 8588e00 Fix doc
| < e348241 Wrap whole DB::DB into &dbcall by moving DB::db into DB::interact
|/  
o 6086d62 Code comment

Here we can understand that:

  1. commits 3e4cc19 and 3df5e8c are not touched and same as 5b1ce15, 8588e00 correspondingly
  2. commits marked by > sign were added in your local repository
  3. commits marked by < sign were removed from remote repository

Because the commit Wrap whole DB::DB into &dbcall by moving DB::db into DB::interact has same name on local and remote repos we can suppose that the e348241 commit was changed and amended. And can see what was changed there:

$ git diff e348241 1e1b4a3
diff --git a/lib/DB/Commands.pm b/lib/DB/Commands.pm
index cb5b237..4f664fa 100644
--- a/lib/DB/Commands.pm
+++ b/lib/DB/Commands.pm
@@ -250,7 +250,7 @@ sub cmd_stepout {

     if( $sharp ) {
         my $frames;
-        1 while caller( 11 + $frames++ );
+        1 while caller( 12 + $frames++ );
         $frames_left =  $frames -$frames_left +1;

         return -2   if $frames_left <= 0; # Do nothing for unexisting frame

But I do not know the option that will show output like this:

$ git log --graph --decorate --pretty=oneline --abbrev-commit --left-right --cherry-mark --boundary --XX-OPTION 8cb6531...1295174
> 1295174 (HEAD -> reimplement) TEMPORARY
--- a/lib/file.pm
+++ b/lib/file.pm
@@ -250,7 +250,7 @@ sub zzzz {

 if( $code ) {
     my $frames;
-        code was
+        code now
     $var;

     return
> 0f477bf Prettify code
> 09630ef Setup $DB::single
= 3e4cc19 Debugger debugging is finished. Remove mark
= 3df5e8c Fix doc
> 1e1b4a3 Wrap whole DB::DB into &dbcall by moving DB::db into DB::interact
--- a/lib/DB/Commands.pm
+++ b/lib/DB/Commands.pm
@@ -250,7 +250,7 @@ sub cmd_stepout {

     if( $sharp ) {
         my $frames;
-        1 while caller( 11 + $frames++ );
+        1 while caller( 12 + $frames++ );
         $frames_left =  $frames -$frames_left +1;

         return -2   if $frames_left <= 0; # Do nothing for unexisting frame

o 6086d62 Code comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.