How to find the hash of branch in Git?

Don't forget that since Git 2.19 (Q2 2018), Git prepares a transition from SHA1 hashes to SHA2: see "Why doesn't Git use more modern SHA?"

With Git 2.25 (Q1 2020), git rev-parse evolves and reflects that possible new hash.

See commit fa26d5e, commit cf02be8, commit 38ee26b, commit 37ab8eb, commit 0370b35, commit 0253e12, commit 45e2ef2, commit 79b0edc, commit 840624f, commit 32a6707, commit 440bf91, commit 0b408ca, commit 2eabd38 (28 Oct 2019), and commit 1bcef51, commit ecde49b (05 Oct 2019) by brian m. carlson (bk2204).
(Merged by Junio C Hamano -- gitster -- in commit 28014c1, 10 Nov 2019)

rev-parse: add a --show-object-format option

Signed-off-by: brian m. carlson

Add an option to print the object format used for input, output, or storage.
This allows shell scripts to discover the hash algorithm in use.

Since the transition plan allows for multiple input algorithms, document that we may provide multiple results for input, and the format that the results may take.
While we don't support this now, documenting it early means that script authors can future-proof their scripts for when we do.

The git rev-parse documentation now includes:

--show-object-format[=(storage|input|output)]:

Show the object format (hash algorithm) used for the repository for storage inside the .git directory, input, or output. For input, multiple algorithms may be printed, space-separated. If not specified, the default is "storage".


With Git 2.29 (Q4 2020), you can make sure what format you must use to read the hash commit of a branch (or any other object).

See commit e023ff0, commit 4feb562, commit 8a06d56, commit c49fe07, commit 02a32db, commit ceaa4b3, commit eff45da, commit b5b46d7, commit c5aecfc, commit e74b606, commit 439d3a1, commit 6c2adf8, commit de5737c, commit e0a646e, commit 6ff6a67, commit 831279d, commit b6e5005, commit 287bb3a, commit 22f1824, commit db00af9, commit 7187eb1, commit 98de0b2, commit a5587b8, commit 66b6d43, commit 2197f87, commit c0b65ea, commit d62607d, commit d482c23, commit 866be6e, commit 4bacb6d, commit 252a4ee, commit 368f3cb, commit abe3db1, commit 08fbc5d, commit 11b6961, commit 9e3bd8a, commit d827bce, commit 094a685 (29 Jul 2020) by brian m. carlson (bk2204).
See commit 800e6a7 (29 Jul 2020) by Johannes Schindelin (dscho).
(Merged by Junio C Hamano -- gitster -- in commit e0ad957, 11 Aug 2020)

docs: add documentation for extensions.objectFormat

Signed-off-by: brian m. carlson
Reviewed-by: Eric Sunshine

Document the extensions.objectFormat config setting.
Warn users not to modify it themselves.

git config now includes in its man page:

extensions.objectFormat

Specify the hash algorithm to use.

The acceptable values are sha1 and > sha256.
If not specified, sha1 is assumed.
It is an error to specify this key unless core.repositoryFormatVersion is 1.

Note that this setting should only be set by git init or git clone.
Trying to change it after initialization will not work and will produce hard-to-diagnose issues.


To be clear, with Git 2.29 (Q4 2020), the recent addition of SHA-256 support is marked as experimental in the documentation.

See commit ff233d8 (16 Aug 2020) by Martin Ågren (none).
(Merged by Junio C Hamano -- gitster -- in commit d1ff741, 24 Aug 2020)

Documentation: mark --object-format=sha256 as experimental

Signed-off-by: Martin Ågren

After eff45daab8 ("repository: enable SHA-256 support by default", 2020-07-29, Git v2.29.0 -- merge listed in batch #6), vanilla builds of Git enable the user to run, e.g.,

git init --object-format=sha256  

and hack away.
This can be a good way to gain experience with the SHA-256 world, e.g., to find bugs that

GIT_TEST_DEFAULT_HASH=sha256 make test  

doesn't spot.

But it really is a separate world: Such SHA-256 repos will live entirely separate from the (by now fairly large) set of SHA-1 repos.
Interacting across the border is possible in principle, e.g., through "diff + apply" (or "format-patch + am"), but even that has its limitations: Applying a SHA-256 diff in a SHA-1 repo works in the simple case, but if you need to resort to -3, you're out of luck.

Similarly, "push + pull" should work, but you really will be operating mostly offset from the rest of the world. That might be ok by the time you initialize your repository, and it might be ok for several months after that, but there might come a day when you're starting to regret your use of [git init --object-format=sha256](https://github.com/git/git/blob/ff233d8dda12657a90d378f2b403bc6c85838c59/Documentation/git-init.txt#L52)<sup>([man](https://git-scm.com/docs/git-init#Documentation/git-init.txt---object-formatltformatgt))</sup> and have dug yourself into a fairly deep hole.

There are currently topics in flight to document our data formats and protocols regarding SHA-256 and in some cases (midx and commit-graph), we're considering adjusting how the file formats indicate which object format to use.

Wherever --object-format is mentioned in our documentation, let's make it clear that using it with "sha256" is experimental.
If we later need to explain why we can't handle data we generated back in 2020, we can always point to this paragraph we're adding here.

By "include::"-ing a small blurb, we should be able to be consistent throughout the documentation and can eventually gradually tone down the severity of this text.
One day, we might even use it to start phasing out --object-format=sha1, but let's not get ahead of ourselves...

There's also extensions.objectFormat, but it's only mentioned three times. Twice where we're adding this new disclaimer and in the third spot we already have a "do not edit" warning. From there, interested readers should eventually find this new one that we're adding here.

Because GIT_DEFAULT_HASH provides another entry point to this functionality, document the experimental nature of it too.

git now includes in its man page:

is used instead. The default is "sha1". THIS VARIABLE IS EXPERIMENTAL! See --object-format in git init.

object-format-disclaimer now includes in its man page:

THIS OPTION IS EXPERIMENTAL!
SHA-256 support is experimental and still in an early stage.

A SHA-256 repository will in general not be able to > share work with "regular" SHA-1 repositories.
It should be assumed that, e.g., Git internal file formats in relation to SHA-256 repositories may change in backwards-incompatible ways.
Only use --object-format=sha256 for testing purposes.


The same Git 2.29 (Q4 2020) make sure that "git clone"(man) will work when one clones from SHA-1 repository, while GIT_DEFAULT_HASH is set to use SHA-256 already.
Before 2.29, that resulted in an unusable repository that half-claims to be SHA-256 repository with SHA-1 objects and refs.
This has been corrected.

See commit 47ac970 (20 Sep 2020) by brian m. carlson (bk2204).
(Merged by Junio C Hamano -- gitster -- in commit b28919c, 29 Sep 2020)

builtin/clone: avoid failure with GIT_DEFAULT_HASH

Reported-by: Matheus Tavares
Signed-off-by: brian m. carlson

If a user is cloning a SHA-1 repository with GIT_DEFAULT_HASH set to "sha256", then we can end up with a repository where the repository format version is 0 but the extensions.objectformat key is set to "sha256".
This is both wrong (the user has a SHA-1 repository) and nonfunctional (because the extension cannot be used in a v0 repository).

This happens because in a clone, we initially set up the repository, and then change its algorithm based on what the remote side tells us it's using.
We've initially set up the repository as SHA-256 in this case, and then later on reset the repository version without clearing the extension.

We could just always set the extension in this case, but that would mean that our SHA-1 repositories weren't compatible with older Git versions, even though there's no reason why they shouldn't be.
And we also don't want to initialize the repository as SHA-1 initially, since that means if we're cloning an empty repository, we'll have failed to honor the GIT_DEFAULT_HASH variable and will end up with a SHA-1 repository, not a SHA-256 repository.

Neither of those are appealing, so let's tell the repository initialization code if we're doing a reinit like this, and if so, to clear the extension if we're using SHA-1.
This makes sure we produce a valid and functional repository and doesn't break any of our other use cases.


The command git rev-parse is your friend, e.g.:

$ git rev-parse development
17f2303133734f4b9a9aacfe52209e04ec11aff4

... or for a remote-tracking branch:

$ git rev-parse origin/master
da1ec1472c108f52d4256049fe1f674af69e785d

This command is generally very useful, since it can parse any of the ways of specifying branch names in git, such as:

git rev-parse master~3
git rev-parse HEAD@{2.days.ago}

... etc.


The short answer to get the hash of the current checked out branch may be

git rev-parse `git branch | cut -d' ' -f2`

Explanation:

Assuming you've checked out develop, you get

> git branch
* develop
> git branch | cut -d' ' -f2
develop
> git rev-parse `git branch | cut -d' ' -f2`
[your hash code]

enjoy :)


The hashes are stored under .git/refs/, e.g. .git/refs/heads/master

But programatically use git rev-parse as suggested by Mark Longair as it's safer.

Tags:

Git