Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create dangling commit without checking out

Tags:

git

Is there a way to silently create a commit that is

  • Not connected to the current branch
  • Not checked out afterwards

like

A-B-C-D-E-F-G   # master
       \   \
        X   Y

Where X and Y are created without the user noticing.

The reasoning:

I am writing a lot of exploratory experiment-code and want to automatically commit the current state when running an experiment. These intermediate states should not end up in my Git history and I do not want to go through the mental overhead of committing before running all the time (or forgetting it every now and then).

The idea is to have a lot of dangling commits that will not be pushed to my remote and may be deleted by garbage collection. Each individual commit SHA1 will be annotated to my experiment results, enabling me to trace back what changes had what effect on the results.

like image 953
Nils Werner Avatar asked Jul 27 '16 15:07

Nils Werner


People also ask

What is a dangling commit?

A dangling commit is a commit which is not associated with reference, i.e., there is no way to reach it. For example, consider the diagram below. Suppose we delete the branch featureX without merging its changes, then commit D will become a dangling commit because there is no reference associated with it.

Does Github delete dangling commits?

If you can't afford to lose issue data, GitHub support can manually delete dangling commits.

Can you commit without add?

Without adding any files, the command git commit won't work. Git only looks to the staging area to find out what to commit. Staging, or adding, files, is possible through the command line, and also possible with most Git interfaces like GitHub Desktop by selecting the lines or files that you'd like to stage.


1 Answers

You can use the git commit-tree command to create a dangling commit.

First, stage the files you want to commit, e.g., by doing git add file.

Next, create a tree from the index.

git write-tree

This will print a hash to stdout. That is the hash of the tree you want to commit. Let's say the hash is 12345678.

Now that you have a tree for the index, you can unstage the changes so you won't commit them "for real" by mistake. (git reset HEAD file.)

Finally, create a commit from that tree.

git commit-tree 12345678 -p HEAD -m "Description"

This creates a new commit and prints its hash to stdout. The commit's parent is HEAD and the comment is Description.

As a reminder, this is a dangling commit and therefore will be subject to GC.

like image 170
Raymond Chen Avatar answered Sep 28 '22 12:09

Raymond Chen