Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git: Are these dangling commits?

Given at the end is an extracted screenshot from a SourceTree branch tree view (there is a gap in the middle of the screenshot)

In that, #1 points to the line which used to be branch 1.7.6.14.X and #2 points to the current status of the same branch.

The commit referred to by #3 and the preceding 8 commits on that line were previously attached to branch 1.7.6.14.X. Then another developer supposedly checked out the same branch and did the fix pointed to by #4. This #4 commit has removed the former 9 commits from branch 1.7.6.14.X and left them dangling.
As a result, the branch 1.7.6.14.X now starts from the original branching point instead of just extending from commit #3.

Running git fsck with --unreachable, --dangling etc doesn't give any errors. I tried --lost-found as well.

However, git fsck <hash of commit #3> produces five dangling commits and a whole bunch of dangling tags:

Checking object directories: 100% (256/256), done.
Checking objects: 100% (3148/3148), done.
dangling commit ec213...
dangling commit ab82a...
dangling commit 7d262...
dangling commit a6f06...
dangling commit 6674a...

I have two questions:

  1. What could have caused this situation (i.e. branch #1 getting detached)?

  2. How can I detect whether there are similar issues in other repositories? (without having to know the hashes of detached commits such as #3)

Commits detached from branch

Update:

We found the answer to question (1). The situation was caused by a force push, to the central bare repo, by a developer who had an older snapshot of the branch.

like image 536
Ishan De Silva Avatar asked Jan 02 '16 10:01

Ishan De Silva


2 Answers

  1. as you said; this is caused by using git push --force
  2. Since all your commits are attainable with a tag; git will never say that hey are dangling, since they are not. They will never be lost nor cleaned up since a tag refers to them.

As to how to find these (for lack of a better word) dangling commits; I didn't find anything purely git, but I came up with a small script that allows detecting them. There might be a way to make this more performant, but is does the trick:

for sha in $(git log --all --pretty=format:"%H")
do
    if [ -z "$(git branch --contains $sha)" ]
    then
        echo "commit not on a branch: $sha"
    fi
done

note I know that the test -z "" isn't very clean, but the return value of git branch is always 0...

like image 27
Chris Maes Avatar answered Oct 17 '22 11:10

Chris Maes


Here is a post Linus Torvalds:

Linus describes what dangling objects are, when they are left behind, and how to view their relationship with branch heads in gitk


What could have caused this situation (i.e. branch #1 getting detached)?

Dangling data is data which is stored in the git repository but is un reachable.
Meaning that you have (added or committed) content which is not accessible in your repository, (no commit or branch is having or pointing to this content)

So the answer is yes, all the commits on branch #1 are not accessible from any commits beside branch #1.


How can I detect whether there are similar issues in other repositories?
(without having to know the hashes of detached commits such as #3)

git fsck --full

This command will check all the dangling content in your repository


There can be 2 kind of dangling content in your repository:

Dangling blob

Change(s) that made it to the staging area/index (once you do git add git calculated the SHA-1 and starting to track the content) but never got committed.

Dangling commit

Commit(s) that isn't linked to any branch or tag either directly or by any of its ascendants.

like image 158
CodeWizard Avatar answered Oct 17 '22 12:10

CodeWizard