a guide to Git‘s core concepts

原文引用https://www.dazhuanlan.com/2019/08/25/5d622c99b2cb2/

a guide to Git‘s core concepts

I‘ve never used another VCS before I learn the Git. So I do not know much about other VCS‘s details. But maybe this is a good thing because you must not apply your past knowledge of another VCS to Git. Many people think that Git is hard to learn. Maybe this is one of reasons.

But complex systems like Git become much easier to understand once you figure out how they really work. Here something that could at least explain some details of how Git works under the hood will be talked about. We are going to take a look at some of Git‘s core concepts including its basic object storage, how commits work, how branches and tags work. So we won’t tell you how one command in Git is used. We want to tell you something behind Git‘s commands. Hopefully, at the end of it all, you‘ll have a solid understanding of these concepts and will be able to use some of Git‘s more advanced features with confidence. So remember that this guide is NOT intended to be a beginner‘s introduction to Git.

Repositories

At the core of Git is the repository. A Git repository is really just a simple key-value data store. This is what is stored in Git:

  • Blobs, which are the most basic data type in Git. Essentially, a blob is just a bunch of bytes; usually a binary representation of a file.
  • Tree objects, which are a bit like directories. Tree objects can contain pointers to blobs and other tree objects.
  • Commit objects, which point to a single tree object, and contain some metadata including the commit author and any parent commits.
  • Tag objects, which point to a single commit object, and cotain some metadata.
  • References, which are pointers to a single object(usually a commit object or a tag object).

The import thing to remember about a Git repository is that it exists entirely in a single .git directory in your project root. The import directories are .git/objects, wherse Git stores all of its objects, and .git/refs, where Git stores all of its references.

Tree Objects

A tree object in Git can be thought of as a directory. It contains a list of blobs(files) and other tree objects(sub-directories).

Given the root tree object, we can recurse through every tree object to figure out the state of the entire working tree. The root tree object, therefore, is essentially a SNAPSHOT of your repository at a given time point. Please be careful to notice the concept SNAPSHOT, because it is one main reason of Git‘s high fficiency.

Commits

A commit object is essentially a pointer that contains a few piece of important metadata. The commit itself has a hash, which is built from a combination of the metadata that it contains:

  • The hash of the tree (the root tree object) at the time of the commit. As we learned in Tree Objects, this means that with a single commit, Git can build the entire working tree by recursing into the tree.

    • The hash of any parent commits. This is what gives a repository its history: every commit has a parent commit, all the way back to the very first commit.
    • The author‘s name and email address, and the time that the changes were authored.
    • The committer‘s name and email address, and the time that the commit was made.
    • The commit message.
git show --format=raw COMMIT-ID

Using this command, we can see the newly-created commit‘s metadata.

Reference

First of all, we need to know that every object in Git is indentified by a hash. But you must remember the hash of every object you want to manipulate. To save you from having to memorize these hashes, Git has references or "refs". A reference is simply a file stored somewhere in .git/refs, containing the hash of a commit object. Git can tell us which commit a reference is pointing to with the show and rev-parse commands.

$ git show rev-parse master
e439c576b191fd9cb797fd9a27f4b7c617abfd21

Git also has a special reference, HEAD. This is a "symbolic" reference which points to the tip of the current branch rather than an actual commit. It is actually possible for HEAD to point directly to a commit object. When this happens, Git will tell you that you are in a "detached HEAD state".

Branches

Branches in Git are very lightweight which is why Git‘s branches are generally thought as its strongest features. The reason branches are so lightweight in Git is because they‘re just references. Two types of branches are local branches and remote-tracking branches.

Tags

There are two types of tags in Git - lightweight tags and annotated tags.

On the surface, these two types of tags are very similar. Both of them are references stored in .git/refs/tags. However, that‘s about as far as the similarities go. Real differences are between lightweight tags and annotated tags.

By default, the command git tag will create a lightweight tag. But pay close attention to this tag which is not a tag object. It is just a reference which points to the current commit object.

Now let‘s see the annotated tags:

    $ git tag -a -m "Tagged 1.0" 1.0

This command will create an annotated tag named 1.0. Here what needs much more attention is that it create a tag object, not a tag reference. A tag object is separate to the commit that it points to. As well as containing a pointer to a commit, tag objects also store a tag message and infomation about the tagger. Tag objects can also be signed with a GPG key to prevent commit or email spoofing.

Merging

Merging in Git is the process of joining two histories(usually branches) together. Say we have created two branches from master and done some work respectively. At this point, the history will look something like this.

Now we can bring the bug fix into master so we can tag it and release it. Let‘s see what happens after merging.

We can see how Git mensions fast-forward during the merge. What this means is that all of the commits in hotfix were directly upstream from master. This allows Git to simply move the master pointer up the tree to hotfix.

Then let‘s try and merge feature-branch into master.

This time, Git wasn‘t able to perform a fast-forward. This is because feature-branch is not directly upstream from master. When coming to this situation, Git actually creates a new "merge" commit whose parents are from feature-branch and master. And this is referred to as a merge commit.

Next we‘ll see how to prevent this kind of non-fast-forward merges by rebasing feature branches before merging them with master.

Rebasing

This part is gonna be hard because of the extrordinay amount of scaremongering around rebasing which you can read from the Internet. First of all, let‘s take a quick look at the cherry-picking. I‘m gonna tell you that cherry-picking exists in a special situation from rebasing.

Cherry-picking

What git cherry-pick does is take one or more commits, and replay them on top of the current commit. It‘s like you get a patch from one commit and apply it on your current commit. All git cherry-pick does is apply one from a commit one by one. But what if you want to play a chain of commits on the other one, e.g., master branch. Actually, you don‘t have to use git cherry-pick command many times.

rebaseing (continued)

    $ git rebase master foo

With the format git rebase <base> <target>, the rebase command will take all of the commits from <target>, and paly them on top of <base> one by one. It does this without actuall modifying <base>, so the end result is a linear history in which <base> can be fast-forward to <target>.

For now, I‘m done. But there will be more contents.

原文地址:https://www.cnblogs.com/petewell/p/11408069.html

时间: 2024-08-14 21:33:09

a guide to Git‘s core concepts的相关文章

(转) Deep Learning in a Nutshell: Core Concepts

Deep Learning in a Nutshell: Core Concepts Share: Posted on November 3, 2015by Tim Dettmers 7 CommentsTagged cuDNN, Deep Learning, Deep Neural Networks, Machine Learning,Neural Networks This post is the first in a series I’ll be writing for Parallel

Xapian实战(二):core concepts

参考资料 core concepts 正文 1. 并发性 xapian不包含任何全局变量,所以多线程编程中,在没有共享资源的情况下可以安全使用xapian.在实际操作中,由于每个线程都可以创建自己的xapian.Database对象,所以这个限制条件完全没有问题.当然如果真的需要在多线程中使用同一个xapian对象,则需要用到mutex的线程锁. 需要注意的是,有些xapian对象包含了其他对象的引用——例如,xapian.Database.get_document()的结果xapian.Doc

Command failed: git -c core.longpaths=true config --get remote.origin.url

「Unable to Connect to GitHub.com For Cloning」Error: Command failed: git -c core.longpaths=true config --get remote.origin.url此处原因应该是因为网络无法透过git://方式将package download下来清除缓存:npm cache clear更改Download方式:git config --global url."https://".insteadOf

Hadoop Yarn core concepts

The fundamental idea of YARN is to split the two major responsibilities of the JobTracker—that is, resource management and job scheduling/monitoring—into separate daemons: a global ResourceManager and a per-application ApplicationMaster (AM). The Res

git ,创建生成 making git-svn work on mac tiger

http://www.mikeheijmans.com/2008/04/make-git-svn-work-on-mac-osx-tiger/ After a few hours of googling and pull some hair out, I have finally figured out how to make git-svn work on Mac OSX 10.4 Tiger. If you have installed git on your Mac using mac-p

我的git与github学习历程

因为想要知道如何把代码放到github上,所以就百度了一下,然后找到一个<如何从github上面拷贝源码>的文章,就先进行练习了下 1.首先到git官网下载git版本控制工具的安装包,下载好双击安装,所有的步骤我都默认的. git官网:http://git-scm.com/download/ 2.然后安装完成我把没打勾的地方都打勾了,然后点击完成就出现如下图蓝色网页和黑色弹框,蓝色网页的网址: file:///D:/Program%20Files/Git/ReleaseNotes.html 看

使用git做服务器端代码的部署

传统部署方案     windows 远程桌面     FTP/SFTP     登录服务器pull github代码     Phing(PHP专业部署工具) git 自动部署流程图   服务器端准备工作:     0. 这些工作都在root或有管理权限的帐号下进行,下面以root为用户,切换到其他用户的时候会提示     1. 确保安装了git     2. 为了安全起见,新建一个专门用于代码部署的无特权用户                useradd -m deployuser     

git进阶

git进阶 1 分支管理 分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习Git的时候,另一个你正在另一个平行宇宙里努力学习SVN. 如果两个平行宇宙互不干扰,那对现在的你也没啥影响.不过,在某个时间点,两个平行宇宙合并了,结果,你既学会了Git又学会了SVN! 分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了.如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险. 现

git warning: LF will be replaced by CRLF in 解决办法

在使用git的时候,每次执行 #git add "目录" git add . 都会提示这样一个警告消息: warning: LF will be replaced by CRLF in XXXXXXXXXXXXXX. 虽然说没有什么影响吧. 不过就是觉得太碍眼了, 按照这样设置就没有问题了: git config core.autocrlf false 这样设置git的配置后在执行add操作就没有问题了.