-
1. ŠŃ Š±Š¾ŃŠ»Š°Š½ŠøŃŠø
- 1.1 Š¢Š°Š»ŅŠøŠ½Š»Š°Ńни боŃŅŠ°ŃŠøŃ Ņ³Š°ŅŠøŠ“а
- 1.2 Git нинг ŅŠøŃŅŠ°Ńа ŃŠ°ŃŠøŃ Šø
- 1.3 Git Š°ŃŠ¾ŃŠø
- 1.4 ŠŠ¾Š¼Š°Š½Š“Š°Š»Š°Ń ŃŠ°ŃŃŠø
- 1.5 Git ни ŃŃŠ½Š°ŃŠøŃ
- 1.6 Git Га Š±ŠøŃŠøŠ½ŃŠø ŃŠ¾Š·Š»Š°ŃлаŃ
- 1.7 ŅŠ°Š½Š“ай ŃŃŠ“ам Š¾Š»ŠøŃ Š¼ŃŠ¼ŠŗŠøŠ½?
- 1.8 Š„ŃŠ»Š¾ŃалаŃ
-
2. Git Š°ŃŠ¾ŃŠ»Š°ŃŠø
- 2.1 Git Š¾Š¼Š±Š¾ŃŠøŠ½Šø ŃŃŠ°ŃŠøŃ
- 2.2 ŠŠ·Š³Š°ŃŠøŃŠ»Š°Ńни Š¾Š¼Š±Š¾Ńга ŃŠ·ŠøŃ
- 2.3 Š¤ŠøŠŗŃŠøŃŠ»Š°ŃŠ»Š°Ń ŃŠ°ŃŠøŃ ŠøŠ½Šø ŠŗŃŃŠøŃ
- 2.4 ŠŠ·Š³Š°ŃŠøŃŠ»Š°Ńни Š±ŠµŠŗŠ¾Ń ŅŠøŠ»ŠøŃ
- 2.5 Š£Š·Š¾Ņ Š¼Š°ŃŠ¾ŃаГаги Š¾Š¼Š±Š¾ŃŠ»Š°Ń билан ŠøŃлаŃ
- 2.6 Š¢Š°Š¼ŅŠ°Š»Š°Ń
- 2.7 Git Га ŃŠ°Ņ³Š°Š»Š»ŃŃŠ»Š°Ń
- 2.8 Š„ŃŠ»Š¾Ńа
-
3. Git Га ŃŠ°ŃŠ¼Š¾ŅŠ»Š°Š½ŠøŃ
- 3.1 Š¢Š°ŃŠ¼Š¾ŅŠ»Š°Š½ŠøŃ Ņ³Š°ŅŠøŠ“а ŠøŠŗŠŗŠø Š¾ŅŠøŠ· ŃŃŠ·
- 3.2 Š¢Š°ŃŠ¼Š¾ŅŠ»Š°Š½ŠøŃ Š²Š° Š±ŠøŃŠ»Š°ŃŠøŃ Š°ŃŠ¾ŃŠ»Š°ŃŠø
- 3.3 Š¢Š°ŃŠ¼Š¾ŅŠ»Š°ŃŠ½Šø боŃŅŠ°ŃŠøŃ
- 3.4 ŠŃ Š¶Š°ŃŠ°ŃŠ½Š»Š°ŃŠøŠ½Šø ŃŠ°ŃŠ¼Š¾ŅŠ»Š°Ń
- 3.5 Š£Š·Š¾Ņ Š¼Š°ŃŠ¾ŃаГаги ŃŠ°ŃŠ¼Š¾ŅŠ»Š°Ń
- 3.6 ŅŠ°Š¹Ńа Š°ŃоŃланиŃ
- 3.7 Š„ŃŠ»Š¾ŃалаŃ
-
4. Git ŃŠµŃŠ²ŠµŃŠ“а
- 4.1 The Protocols
- 4.2 Getting Git on a Server
- 4.3 Sizning SSH ochiq (public) kalitingizni generatsiyalash
- 4.4 Setting Up the Server
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Third Party Hosted Options
- 4.10 Š„ŃŠ»Š¾ŃалаŃ
-
5. Distributed Git
- 5.1 Distributed Workflows
- 5.2 Contributing to a Project
- 5.3 Maintaining a Project
- 5.4 Summary
-
6. GitHub
-
7. Git Tools
- 7.1 Revision Selection
- 7.2 Interactive Staging
- 7.3 Stashing and Cleaning
- 7.4 Signing Your Work
- 7.5 Searching
- 7.6 Rewriting History
- 7.7 Reset Demystified
- 7.8 Advanced Merging
- 7.9 Rerere
- 7.10 Debugging with Git
- 7.11 Qism modullar (Submodule)
- 7.12 Bundling
- 7.13 Replace
- 7.14 Credential Storage
- 7.15 Summary
-
8. Customizing Git
- 8.1 Git Configuration
- 8.2 Git Attributes
- 8.3 Git Hooks
- 8.4 An Example Git-Enforced Policy
- 8.5 Summary
-
9. Git and Other Systems
- 9.1 Git as a Client
- 9.2 Migrating to Git
- 9.3 Summary
-
10. Git Internals
- 10.1 Plumbing and Porcelain
- 10.2 Git Objects
- 10.3 Git References
- 10.4 Packfiles
- 10.5 The Refspec
- 10.6 Transfer Protocols
- 10.7 Maintenance and Data Recovery
- 10.8 Environment Variables
- 10.9 Summary
-
A1. Appendix A: Git in Other Environments
- A1.1 Graphical Interfaces
- A1.2 Git in Visual Studio
- A1.3 Git in Eclipse
- A1.4 Git in Bash
- A1.5 Git in Zsh
- A1.6 Git in Powershell
- A1.7 Summary
-
A2. Appendix B: Embedding Git in your Applications
- A2.1 Command-line Git
- A2.2 Libgit2
- A2.3 JGit
-
A3. Appendix C: Git Commands
- A3.1 Setup and Config
- A3.2 Getting and Creating Projects
- A3.3 Basic Snapshotting
- A3.4 Branching and Merging
- A3.5 Sharing and Updating Projects
- A3.6 Inspection and Comparison
- A3.7 Debugging
- A3.8 Patching
- A3.9 Email
- A3.10 External Systems
- A3.11 Administration
- A3.12 Plumbing Commands
10.3 Git Internals - Git References
Git References
You can run something like git log 1a410e
to look through your whole history, but you still have to remember that 1a410e
is the last commit in order to walk that history to find all those objects.
You need a file in which you can store the SHA-1 value under a simple name so you can use that pointer rather than the raw SHA-1 value.
In Git, these are called āreferencesā or ārefs;ā you can find the files that contain the SHA-1 values in the .git/refs
directory.
In the current project, this directory contains no files, but it does contain a simple structure:
$ find .git/refs
.git/refs
.git/refs/heads
.git/refs/tags
$ find .git/refs -type f
To create a new reference that will help you remember where your latest commit is, you can technically do something as simple as this:
$ echo "1a410efbd13591db07496601ebc7a059dd55cfe9" > .git/refs/heads/master
Now, you can use the head reference you just created instead of the SHA-1 value in your Git commands:
$ git log --pretty=oneline master
1a410efbd13591db07496601ebc7a059dd55cfe9 third commit
cac0cab538b970a37ea1e769cbbde608743bc96d second commit
fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
You arenāt encouraged to directly edit the reference files.
Git provides a safer command to do this if you want to update a reference called update-ref
:
$ git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9
Thatās basically what a branch in Git is: a simple pointer or reference to the head of a line of work. To create a branch back at the second commit, you can do this:
$ git update-ref refs/heads/test cac0ca
Your branch will contain only work from that commit down:
$ git log --pretty=oneline test
cac0cab538b970a37ea1e769cbbde608743bc96d second commit
fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit
Now, your Git database conceptually looks something like this:

When you run commands like git branch (branchname)
, Git basically runs that update-ref
command to add the SHA-1 of the last commit of the branch youāre on into whatever new reference you want to create.
The HEAD
The question now is, when you run git branch (branchname)
, how does Git know the SHA-1 of the last commit?
The answer is the HEAD file.
The HEAD file is a symbolic reference to the branch youāre currently on. By symbolic reference, we mean that unlike a normal reference, it doesnāt generally contain a SHA-1 value but rather a pointer to another reference. If you look at the file, youāll normally see something like this:
$ cat .git/HEAD
ref: refs/heads/master
If you run git checkout test
, Git updates the file to look like this:
$ cat .git/HEAD
ref: refs/heads/test
When you run git commit
, it creates the commit object, specifying the parent of that commit object to be whatever SHA-1 value the reference in HEAD points to.
You can also manually edit this file, but again a safer command exists to do so: symbolic-ref
.
You can read the value of your HEAD via this command:
$ git symbolic-ref HEAD
refs/heads/master
You can also set the value of HEAD:
$ git symbolic-ref HEAD refs/heads/test
$ cat .git/HEAD
ref: refs/heads/test
You canāt set a symbolic reference outside of the refs style:
$ git symbolic-ref HEAD test
fatal: Refusing to point HEAD outside of refs/
Tags
We just finished discussing Gitās three main object types, but there is a fourth. The tag object is very much like a commit object ā it contains a tagger, a date, a message, and a pointer. The main difference is that a tag object generally points to a commit rather than a tree. Itās like a branch reference, but it never moves ā it always points to the same commit but gives it a friendlier name.
As discussed in Git Š°ŃŠ¾ŃŠ»Š°ŃŠø, there are two types of tags: annotated and lightweight. You can make a lightweight tag by running something like this:
$ git update-ref refs/tags/v1.0 cac0cab538b970a37ea1e769cbbde608743bc96d
That is all a lightweight tag is ā a reference that never moves.
An annotated tag is more complex, however.
If you create an annotated tag, Git creates a tag object and then writes a reference to point to it rather than directly to the commit.
You can see this by creating an annotated tag (-a
specifies that itās an annotated tag):
$ git tag -a v1.1 1a410efbd13591db07496601ebc7a059dd55cfe9 -m 'test tag'
Hereās the object SHA-1 value it created:
$ cat .git/refs/tags/v1.1
9585191f37f7b0fb9444f35a9bf50de191beadc2
Now, run the cat-file
command on that SHA-1 value:
$ git cat-file -p 9585191f37f7b0fb9444f35a9bf50de191beadc2
object 1a410efbd13591db07496601ebc7a059dd55cfe9
type commit
tag v1.1
tagger Scott Chacon <schacon@gmail.com> Sat May 23 16:48:58 2009 -0700
test tag
Notice that the object entry points to the commit SHA-1 value that you tagged. Also notice that it doesnāt need to point to a commit; you can tag any Git object. In the Git source code, for example, the maintainer has added their GPG public key as a blob object and then tagged it. You can view the public key by running this in a clone of the Git repository:
$ git cat-file blob junio-gpg-pub
The Linux kernel repository also has a non-commit-pointing tag object ā the first tag created points to the initial tree of the import of the source code.
Remotes
The third type of reference that youāll see is a remote reference.
If you add a remote and push to it, Git stores the value you last pushed to that remote for each branch in the refs/remotes
directory.
For instance, you can add a remote called origin
and push your master
branch to it:
$ git remote add origin git@github.com:schacon/simplegit-progit.git
$ git push origin master
Counting objects: 11, done.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (7/7), 716 bytes, done.
Total 7 (delta 2), reused 4 (delta 1)
To git@github.com:schacon/simplegit-progit.git
a11bef0..ca82a6d master -> master
Then, you can see what the master
branch on the origin
remote was the last time you communicated with the server, by checking the refs/remotes/origin/master
file:
$ cat .git/refs/remotes/origin/master
ca82a6dff817ec66f44342007202690a93763949
Remote references differ from branches (refs/heads
references) mainly in that theyāre considered read-only.
You can git checkout
to one, but Git wonāt point HEAD at one, so youāll never update it with a commit
command.
Git manages them as bookmarks to the last known state of where those branches were on those servers.