git 代理 git_如何不再害怕GIT

git 代理 git

了解减少不确定性的机制 (Understanding the machinery to whittle away the uncertainty)
到底什么是Git? (What is Git anyway?)

“It’s a version control system.”

“这是一个版本控制系统。”

我为什么需要它? (Why do I need it?)

“To version control, silly.”

“对于版本控制,很愚蠢。”

Alright, alright, I’m not being too helpful, yet. Here’s the basic idea: As projects get too large, with too many contributors, it gets impossible to track who did what and when. Did someone introduce a change that broke the entire system? How do you figure out what that change was? How do you go back to how things were before? Back to the unbroken wonderland?

好吧,好吧,我还没有太有帮助。 这是一个基本思想:随着项目变得越来越大,贡献者太多,就无法追踪谁在何时何地做了什么。 有人引入了破坏整个系统的更改吗? 您如何确定这种变化是什么? 您如何回到过去的状态? 回到不间断的仙境?

I’ll take it a step further — say not a project with many contributors, just a small project with you as the creator, maintainer and distributor: You create a new feature for this project, which introduces subtle bugs you find out later. You don’t remember what changes you made to the existing code base to create this new feature. Problem?

我将进一步走下去-不要说一个有很多贡献者的项目,而应该是一个由您作为创建者,维护者和发行者的小项目:您为此项目创建了一个新功能,其中引入了一些细微的错误,这些错误将在以后发现。 您不记得您为创建此新功能而对现有代码库进行了哪些更改。 问题?

The answer to all these problems is versioning! Having versions for everything you’ve coded ensures you know who made the changes, what changes and exactly where, since the beginning of the project!

所有这些问题的答案就是版本控制! 自项目开始以来,拥有所有已编码内容的版本,可确保您知道更改的对象,更改的内容以及确切的位置!

And now, I invite you to stop thinking of (g)it as a blackbox, open it up and find out what treasures await. Figure out how Git works, and you’ll never again have a problem making things work. Once you’re through this, I promise you’ll realise the folly of doing what the XKCD comic above says. That is exactly what versioning is trying to prevent.

现在,我邀请您不要再将其视为黑匣子,打开它,看看有什么珍宝在等待。 弄清楚Git的工作原理,使工作正常,您再也不会遇到问题。 完成此操作后,我保证您会意识到按照上面的XKCD漫画所说的做事很愚蠢。 这正是版本控制要防止的事情。

怎么Git? (How to Git?)

I am assuming you know the basic commands in Git, or have heard about them and used them at least once. If not, here’s a basic vocabulary to help you get started.

我假设您知道Git中的基本命令,或者听说过并至少使用了一次。 如果没有,这是帮助您入门的基本词汇。

Repository: a place for storing things. With Git, this means your code folder

仓库 :一个存放东西的地方。 使用Git,这意味着您的代码文件夹

head: A “pointer” to the latest code you were working on

head:指向您正在使用的最新代码的“指针”

add: An action to ask Git to track a file

添加:要求Git跟踪文件的动作

commit: An action to save the current state — such that one can revisit this state if needed

commit:一种保存当前状态的动作,以便在需要时可以重新访问该状态

remote: A repository that isn’t local. Can be in another folder or in the cloud (for example: Github): helps other people to easily collaborate, as they don’t have to get a copy from your system — they can just get it from the cloud. Also, ensures you have a backup in case you break your laptop

远程:不是本地的存储库。 可以位于其他文件夹或云中(例如:Github):帮助其他人轻松协作,因为他们不必从您的系统中获取副本-他们可以从云中获取它。 此外,请确保您有备份以防万一损坏笔记本电脑

pull: An action to get updated code from the remote

拉:从远程获取更新代码的操作

push: An action to send updated code to the remote

push:将更新的代码发送到远程的动作

merge: An action to combine two different versions of code

合并:合并两个不同版本的代码的动作

status: Displays information about current repository status

status:显示有关当前存储库状态的信息

在哪里Git? (Where to Git?)

Introducing the magic controlled by a hidden folder: .git/

引入由隐藏文件夹控制的魔术: .git/

In every git repository, you’ll see something like this

在每个git存储库中,您都会看到类似的内容

$ tree .git/
.git/
├── HEAD
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   └── update.sample
├── info
│   └── exclude
├── objects
│   ├── info
│   └── pack
└── refs
    ├── heads
    └── tags
8 directories, 14 files

This is how Git controls and manages your entire project. We will go into all the important bits, one by one.

这就是Git控制和管理整个项目的方式。 我们将一一探讨所有重要的方面。

Git consists of 3 parts: the object store, the index and the working directory.

Git由三部分组成:对象存储,索引和工作目录。

对象库 (The Object Store)

This is how Git stores everything internally. For every file in your project that you add, Git generates a hash for the file and stores the file under that hash. For example, if I now create a helloworld file and do git add helloworld (which is telling Git to add the file called helloworld to the git object store), I get something like this:

这就是Git在内部存储所有内容的方式。 对于项目中add每个文件,Git都会为该文件生成一个哈希,并将该文件存储在该哈希下。 例如,如果我现在创建一个helloworld文件并执行git add helloworld (这是告诉Git将名为helloworld的文件添加到git对象存储中),我将得到以下内容:

$ tree .git/
.git/
├── HEAD
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   └── update.sample
├── index
├── info
│   └── exclude
├── objects
│   ├── a0
│   │   └── 423896973644771497bdc03eb99d5281615b51
│   ├── info
│   └── pack
└── refs
    ├── heads
    └── tags
9 directories, 16 files

A new object has been generated! For those interested in going under the hood, Git internally uses the hash-object command like so:

已生成一个新对象! 对于有兴趣的人,Git在内部使用hash-object命令,如下所示:

$ git hash-object helloworld
a0423896973644771497bdc03eb99d5281615b51

Yes, it’s the same hash we see under the objects folder. Why the subdirectory with the first two characters of the hash? It makes searching faster.

是的,这与我们在对象文件夹下看到的哈希相同。 为什么子目录中带有哈希的前两个字符? 它使搜索速度更快。

Then, Git creates an object with the name as the above hash, compresses our given file and stores it there. Hence, you can also actually see the contents of the object!

然后,Git创建一个名称为上述哈希的对象,压缩给定的文件并将其存储在该文件中。 因此,您实际上还可以看到对象的内容!

$ git cat-file a0423896973644771497bdc03eb99d5281615b51 -p
hello world!

This is all under the hood. You’d never use cat-file in day to day adds. You’ll simply add, and let Git handle the rest.

这一切都在幕后。 您永远不会在日常添加中使用cat文件 。 您只需add ,然后让Git处理其余的事情。

That’s our first Git command, done and dusted.

这是我们的第一个Git命令,已完成并已完成。

git add creates a hash, compresses the file and adds the compressed object to the object store.

git add 创建一个哈希,压缩文件并将压缩后的对象添加到对象存储中。

工作目录 (The working directory)

As the name suggests, this is where you work. All files you create and edit are in the working directory. I created a new file, byeworld and ran git status:

顾名思义,这就是您工作的地方。 您创建和编辑的所有文件都在工作目录中。 我创建了一个新文件, byeworld并运行git status

$ git status
On branch master
No commits yet
Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
new file:   helloworld
Untracked files:
  (use "git add <file>..." to include in what will be committed)
byeworld

Untracked files are files in the working directory we haven’t asked git to manage.

未跟踪的文件是我们没有要求git管理的工作目录中的文件。

Had there been nothing we had done in the working directory, we’d get the following message:

如果在工作目录中什么也没做,我们将得到以下消息:

$ git status
On branch master
nothing to commit, working tree clean

which I’m pretty sure you understand now. Ignore the branch and commit for now. The key is, the working tree(directory) is clean.

我敢肯定,您现在已经明白了。 忽略分支并立即提交。 关键是,工作树(目录)是干净的。

索引 (The Index)

This is the core of Git. Also known as the staging area. The index stores the mapping of files to the objects in the object store. This is where the commits come in. The best way to see this is to test it out!

这是Git的核心。 也称为暂存区。 索引存储文件到对象存储库中对象的映射。 这就是commits的来源。查看此内容的最佳方法是对其进行测试!

Let us commit our addition of the file helloworld

让我们提交文件helloworld

$ git commit -m "Add helloworld"
[master (root-commit) a39b9fd] Add helloworld
 1 file changed, 1 insertion(+)
 create mode 100644 helloworld

Back to our tree:

回到我们的树上:

$ tree .git/
.git/
├── COMMIT_EDITMSG
├── HEAD
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   └── update.sample
├── index
├── info
│   └── exclude
├── logs
│   ├── HEAD
│   └── refs
│       └── heads
│           └── master
├── objects
│   ├── a0
│   │   └── 423896973644771497bdc03eb99d5281615b51
│   ├── a3
│   │   └── 9b9fdd624c35eee08a36077f411e009da68c2f
│   ├── fb
│   │   └── 26ca0289762a454db2ef783c322fedfc566d38
│   ├── info
│   └── pack
└── refs
    ├── heads
    │   └── master
    └── tags
14 directories, 22 files

Ah, interesting! We have 2 new objects in our object store, and some stuff we don’t understand yet in the logs and refs. Going back to our friend cat-file:

啊,有趣! 我们在对象存储中有2个新对象,并且在日志和引用中尚不了解某些内容。 回到我们的朋友cat-file

$ git cat-file a39b9fdd624c35eee08a36077f411e009da68c2f -p
tree fb26ca0289762a454db2ef783c322fedfc566d38
author = <=> 1537700068 +0100
committer = <=> 1537700068 +0100
Add helloworld
$ git cat-file fb26ca0289762a454db2ef783c322fedfc566d38 -p
100644 blob a0423896973644771497bdc03eb99d5281615b51 helloworld

As you can guess, the first object is the commit metadata: who did what and why, with a tree. The second object, is the actual tree. If you understand unix file system, you’ll know exactly what this is.

如您所料,第一个对象是提交元数据:谁用树做了什么以及为什么做。 第二个对象是实际的树。 如果您了解Unix文件系统,那么您将确切知道这是什么。

The tree in Git corresponds to the Git file system. Everything is either a tree (directory) or a blob (file) and with each commit, Git stores the tree information as well, to tell itself: this is how the working directory should look at this point. Note that the tree points to a specific object of each file it contains (the hash).

Git中的tree对应于Git文件系统。 一切都是树(目录)或Blob(文件),每次提交时,Git也会存储树信息以告诉自己:这是工作目录在这一点上的外观。 请注意,树指向它包含的每个文件的特定对象(哈希)。

It’s time to talk about branches! Our first commit added some other stuff to .git/ as well. Our interest is now in .git/refs/heads/master:

现在该谈论分支了 ! 我们的第一次提交也向.git/添加了其他内容。 现在,我们对.git/refs/heads/master感兴趣:

$ cat .git/refs/heads/master 
a39b9fdd624c35eee08a36077f411e009da68c2f

Here’s what you need to know about branches:

这是您需要了解的分支机构:

A branch in Git is a lightweight movable pointer to one of these commits. The default branch name in Git is master.
Git中的分支是指向这些提交之一的轻量级可移动指针。 Git中的默认分支名称是master。

Eh, what? I like to think of branches as a fork in your code. You want to make some changes, but you don’t want to break things. You decide to have a stronger demarcation than the commit log, and that’s where branches come in. master is the default branch, also used as the de-facto production branch. Hence, the creation of the above file. As you can guess by the contents of the file, it points to our first commit. Hence, it’s a pointer to a commit.

嗯什么 我喜欢将分支视为代码中的分支。 您想进行一些更改,但是您不想破坏事情。 你决定有较强的分界比提交日志,而这也正是分支进来, master是默认的分支,也被用来作为事实上的分公司生产。 因此,以上文件的创建。 您可以通过文件的内容来猜测,它指向我们的第一次提交。 因此,它是提交的指针。

Let’s explore this further. Say, I create a new branch:

让我们进一步探讨。 说,我创建一个新分支:

$ git branch the-ending
$ git branch
* master
  the-ending

There we have it, a new branch! As you can guess, a new entry must have been added to .git/refs/heads/ and since there is no extra commit, it should point to our first commit as well, just like master.

在那里,有一个新的分支! 如您所料,必须在.git/refs/heads/添加一个新条目,并且由于没有多余的提交,因此它也应指向我们的第一个提交,就像master一样。

$ cat .git/refs/heads/the-ending a39b9fdd624c35eee08a36077f411e009da68c2f

Yup, exactly! Now, remember byeworld? That file was still untracked, so no matter what branch you shift to, that file would always be there. Say, I want to switch to this branch now, so I’ll checkout the branch, like a smokeshow.

是的,完全是! 现在,还记得byeworld吗? 该文件仍未跟踪,因此无论您转移到哪个分支,该文件将始终存在。 说,我现在想切换到该分支,所以我将像烟熏表演一样checkout该分支

$ git checkout the-ending
Switched to branch 'the-ending'
$ git branch
  master
* the-ending

Now, under the hood, Git would change all contents of the working directory to match the content pointed by the branch commit. For now, since this is exactly the same as master, it looks the same.

现在,在后台,Git将更改工作目录的所有内容以匹配分支提交所指向的内容。 现在,由于它与master完全相同,因此外观相同。

I add and commit the byeworld file.

addcommit byeworld文件。

What do you expect to change in the objects folder?

您希望objects文件夹中发生什么变化?

What do you expect to change in the refs/heads folder?

您希望在refs/heads文件夹中进行哪些更改?

Think about this before moving forward.

在前进之前,请考虑一下。

$ tree .git/
.git/
├── COMMIT_EDITMSG
├── HEAD
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   └── update.sample
├── index
├── info
│   └── exclude
├── logs
│   ├── HEAD
│   └── refs
│       └── heads
│           ├── master
│           └── the-ending
├── objects
│   ├── 0b
│   │   └── 17be9dbc34c5a5fbb0b94d57680968efd035ca
│   ├── a0
│   │   └── 423896973644771497bdc03eb99d5281615b51
│   ├── a3
│   │   └── 9b9fdd624c35eee08a36077f411e009da68c2f
│   ├── b3
│   │   └── 00387d818adbbd6e7cc14945fdf4c895de6376
│   ├── d1
│   │   └── 8affe001488123b496ceb34d8b13b120ab4cb6
│   ├── fb
│   │   └── 26ca0289762a454db2ef783c322fedfc566d38
│   ├── info
│   └── pack
└── refs
    ├── heads
    │   ├── master
    │   └── the-ending
    └── tags
17 directories, 27 files

3 new objects — 1 for add, 2 for commit! Makes sense? What do you think the objects contain?

3个新对象-1个用于添加,2个用于提交! 说得通? 您认为这些物件包含什么?

  • Commit metadata

    提交元数据
  • add object contents

    add对象内容

  • Tree description

    树描述

The last part of the picture is: how does this commit metadata work with the previous commit metadata(s). Well, cat-file!

图片的最后一部分是:此提交元数据如何与先前的提交元数据一起工作。 好吧, cat-file

$ git cat-file 0b17be9dbc34c5a5fbb0b94d57680968efd035ca -p
100644 blob d18affe001488123b496ceb34d8b13b120ab4cb6 byeworld
100644 blob a0423896973644771497bdc03eb99d5281615b51 helloworld
$ git cat-file b300387d818adbbd6e7cc14945fdf4c895de6376 -p
tree 0b17be9dbc34c5a5fbb0b94d57680968efd035ca
parent a39b9fdd624c35eee08a36077f411e009da68c2f
author = <=> 1537770989 +0100
committer = <=> 1537770989 +0100
add byeworld
$ git cat-file d18affe001488123b496ceb34d8b13b120ab4cb6 -p
Bye world!
$ cat .git/refs/heads/the-ending 
b300387d818adbbd6e7cc14945fdf4c895de6376

Do you see it in bold? The parent pointer! And it’s exactly how you thought about it — a linked list, linking the commits together!

您以粗体显示吗? 父指针! 这正是您的想法-链接列表,将提交链接在一起!

And do you see the branch implementation? It points to a commit, the latest one we did after checking out! Of course, the master should still be pointing to the helloworld commit, right?

您看到分支实现了吗? 它指向一次提交,这是我们签出后所做的最新一次! 当然,master应该仍然指向helloworld commit,对吗?

$ cat .git/refs/heads/master a39b9fdd624c35eee08a36077f411e009da68c2f

Alright, we have been through a lot, let’s summarise it up to here.

好吧,我们已经经历了很多事情,让我们总结一下。

TL; DR (TL;DR)

Git works with objects — compressed versions of files you’re asking Git to track.

Git适用于对象-您要Git跟踪的文件的压缩版本。

Each object has an ID (a hash generated by Git based on contents of the file).

每个对象都有一个ID(Git根据文件内容生成的哈希值)。

Every time you add a file, Git adds a new object to the object store. This is exactly why you can’t deal with very large files in Git — it stores the entire file each time you add changes, not the diff (contrary to popular belief).

每次add文件时,Git都会向对象存储中添加一个新对象。 这就是为什么您不能在Git中处理非常大的文件的原因 -每次add更改时,它都会存储整个文件,而不是diff(与流行的看法相反)。

Every commit creates 2 objects:

每次提交都会创建2个对象:

  1. The tree: An ID for the tree, which acts exactly like a unix directory: it points to other trees (directories) or blobs(files): This builds up the entire directory structure based on the objects present at that time. Blobs are represented by the current objects created by add.

    的ID,其作用完全类似于unix目录:它指向其他树(目录)或blob(文件):这将基于当时存在的对象构建整个目录结构。 Blob由add创建的当前对象表示。

  2. The commit metadata: An ID for the commit, who made the commit, a tree that represents the commit, commit message and parent commit. Forms a linked list structure linking commits together.

    提交元数据提交的ID(进行提交的人),代表提交,提交消息和父提交的树。 形成一个链接列表结构,将提交链接在一起。

Branches are pointers to commit metadata objects, all stored in .git/refs/heads

分支是提交元数据对象的指针,所有存储在.git/refs/heads

That’s all for the understanding behind the scenes! In the next part, we’ll go through some of the Git actions that give people nightmares:

这就是幕后的了解! 在下一部分中 ,我们将介绍一些让人感到恶梦的Git动作:

reset, merge, pull, push, fetch and how they modify the internal structure in .git/.

reset, merge, pull, push, fetch以及它们如何修改.git/的内部结构。

Other stories in this series:

本系列中的其他故事:

Enjoyed this? Don’t miss a post again — subscribe to my mailing list!

喜欢这个吗? 不要再错过任何帖子-订阅我的邮件列表!

翻译自: https://www.freecodecamp.org/news/how-not-to-be-afraid-of-git-anymore-fe1da7415286/

git 代理 git

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值