首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Git是什么,如何使用

Git是什么,如何使用

作者头像
洋仔聊编程
发布2022-05-10 15:07:38
4940
发布2022-05-10 15:07:38
举报
  • 声明:本博客内容完全来自于Git官网, 总结整理学习个人所需知识
  • 基础
    • 本质
    • 从根本上来讲 Git 是一个内容寻址(content-addressable)文件系统,并在此之上提供了一个版本控制系统的用户界面。
    • Git 的核心部分是一个简单的键值对数据库(key-value data store)。 你可以向该数据库插入任意类型的内容,它会返回一个键值,通过该键值可以在任意时刻再次检索(retrieve)该内容。
    • Git 以一种类似于 UNIX 文件系统的方式存储内容,但作了些许简化。 所有内容均以树对象和数据对象的形式存储,其中树对象对应了 UNIX 中的目录项,数据对象则大致上对应了 inodes 或文件内容。 一个树对象包含了一条或多条树对象记录(tree entry),每条记录含有一个指向数据对象或者子树对象的 SHA-1 指针,以及相应的模式、类型、文件名信息。
    • 状态
    • 工作目录下的每一个文件都不外乎这两种状态:已跟踪或未跟踪。 已跟踪的文件是指那些被纳入了版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后,它们的状态可能处于未修改,已修改或已放入暂存区。 工作目录中除已跟踪文件以外的所有其它文件都属于未跟踪文件,它们既不存在于上次快照的记录中,也没有放入暂存区。 初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,并处于未修改状态。
    • 存储修改
    • 编辑过某些文件之后,由于自上次提交后你对它们做了修改,Git 将它们标记为已修改文件。 我们逐步将这些修改过的文件放入暂存区,然后提交所有暂存了的修改,如此反复。
    • 请记住,提交时记录的是放在暂存区域的快照。 任何还未暂存的仍然保持已修改状态,可以在下次提交时纳入版本管理。 每一次运行提交操作,都是对你项目作一次快照,以后可以回到这个状态,或者进行比较 。
    • Git 保存的不是文件的变化或者差异,而是一系列不同时刻的文件快照。在进行提交操作时,Git 会保存一个提交对象(commit object)。该提交对象会包含一个指向暂存内容快照的指针。 但不仅仅是这样,该提交对象还包含了作者的姓名和邮箱、提交时输入的信息以及指向它的父对象的指针。首次提交产生的提交对象没有父对象,普通提交操作产生的提交对象有一个父对象,而由多个分支合并产生的提交对象有多个父对象
    • 暂存操作会为每一个文件计算校验和(使用 SHA-1 哈希算法),然后会把当前版本的文件快照保存到 Git 仓库中(Git 使用 blob 对象来保存它们),最终将校验和加入到暂存区域等待提交。
    • 使用 git commit 进行提交操作时,Git 会先计算每一个子目录(本例中只有项目根目录)的校验和,然后在 Git 仓库中这些校验和保存为树对象。 随后,Git 便会创建一个提交对象,它除了包含上面提到的那些信息外,还包含指向这个树对象(项目根目录)的指针。如此一来,Git 就可以在需要的时候重现此次保存的快照。
    • 分支
    • Git 的分支,其实本质上仅仅是指向提交对象的可变指针。 Git 的默认分支名字是 master。 在多次提交操作之后,你其实已经有一个指向最后那个提交对象的 master 分支。 它会在每次的提交操作中自动向前移动。 注意:Git 的 “master” 分支并不是一个特殊分支。 它就跟其它分支完全没有区别。 之所以几乎每一个仓库都有 master 分支,是因为 git init 命令默认创建它,并且大多数人都懒得去改动它。
    • 分支切换会改变你工作目录中的文件,在切换分支时,一定要注意你工作目录里的文件会被改变。 如果是切换到一个较旧的分支,你的工作目录会恢复到该分支最后一次提交时的样子。 如果 Git 不能干净利落地完成这个任务,它将禁止切换分支。
    • Git 的分支实质上仅是包含所指对象校验和(长度为 40 的 SHA-1 值字符串)的文件,所以它的创建和销毁都异常高效。 创建一个新分支就相当于往一个文件中写入 41 个字节(40 个字符和 1 个换行符)
    • 切换分支时,要留意你的工作目录和暂存区里那些还没有被提交的修改,它可能会和你即将检出的分支产生冲突从而阻止 Git 切换到该分支。 最好的方法是,在你切换分支之前,保持好一个干净的状态。
    • 如果你在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,Git 就没法干净的合并它们。 如果你对 #53 问题的修改和有关 hotfix 的修改都涉及到同一个文件的同一处,在合并它们的时候就会产生合并冲突,遇到冲突时的分支合并时,合理修改冲突文件
    • 远程分支
    • 远程引用是对远程仓库的引用(指针),包括分支、标签等等。 你可以通过 git ls-remote (remote) 来显式地获得远程引用的完整列表,或者通过 git remote show (remote) 获得远程分支的更多信息。 然而,一个更常见的做法是利用远程跟踪分支。
    • 远程跟踪分支是远程分支状态的引用,它们以 (remote)/(branch) 形式命名。 例如,如果你想要看你最后一次与远程仓库 origin 通信时 master 分支的状态,你可以查看 origin/master 分支。 你与同事合作解决一个问题并且他们推送了一个 iss53 分支,你可能有自己的本地 iss53 分支;但是在服务器上的分支会指向 origin/iss53 的提交。
    • 例子: 假设你的网络里有一个在 git.ourcompany.com 的 Git 服务器。 如果你从这里克隆,Git 的 clone 命令会为你自动将其命名为 origin,拉取它的所有数据,创建一个指向它的 master 分支的指针,并且在本地将其命名为 origin/master。 Git 也会给你一个与 origin 的 master 分支在指向同一个地方的本地 master 分支,这样你就有工作的基础。
    • 推送
    • 当你想要公开分享一个分支时,需要将其推送到有写入权限的远程仓库上。 本地的分支并不会自动与远程仓库同步 - 你必须显式地推送想要分享的分支。 这样,你就可以把不愿意分享的内容放到私人分支上,而将需要和别人协作的内容推送到公开分支。
    • 如果希望和别人一起在名为 serverfix 的分支上工作,你可以像推送第一个分支那样推送它。 运行 git push (remote) (branch) : git push origin lyy(将lyy分支推送到origin所代表的远程服务器中)
    • 当推送时,会让输入账号和密码,如果不想每次都输入账号和密码,设置”凭证存储“:https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E5%87%AD%E8%AF%81%E5%AD%98%E5%82%A8#r_credential_caching
    • 跟踪分支
    • 从一个远程跟踪分支检出一个本地分支会自动创建一个叫做 “跟踪分支”(有时候也叫做 “上游分支”)。 跟踪分支是与远程分支有直接关系的本地分支。 如果在一个跟踪分支上输入 git pull,Git 能自动地识别去哪个服务器上抓取、合并到哪个分支。
    • 当首次克隆一个仓库时,它通常会自动地创建一个跟踪 origin/master 的 master 分支。
    • 拉取
    • 当 git fetch 命令从服务器上抓取本地没有的数据时,它并不会修改工作目录中的内容。 它只会获取数据然后让你自己合并。 然而,有一个命令叫作 git pull 在大多数情况下它的含义是一个 git fetch 紧接着一个 git merge 命令。
    • 如果有一个像之前章节中演示的设置好的跟踪分支,不管它是显式地设置还是通过 clone 或 checkout 命令为你创建的,git pull 都会查找当前分支所跟踪的服务器与分支,从服务器上抓取数据然后尝试合并入那个远程分支。
    • 变基(vs 合并)
    • 变基可以使得提交历史更加整洁。
    • 无论是通过变基,还是通过三方合并,整合的最终结果所指向的快照始终是一样的,只不过提交历史不同罢了。 变基是将一系列提交按照原有次序依次应用到另一分支上,可能会清楚一部分提交历史,而合并是把最终结果合在一起,不会清除部分提交历史。
    • 只对尚未推送或分享给别人的本地修改执行变基操作清理历史,从不对已推送至别处的提交执行变基操作。
    • 详情:https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%8F%98%E5%9F%BA
    • 总流程图(其中:Workspace:工作区   Index / Stage:暂存区  Repository:仓库区(或本地仓库) Remote:远程仓库

git init :初始化项目(在项目目录下才可)

git add file_name : 将file_name添加到git管理中 或者 把已跟踪的文件放到暂存区(运行了 git add 之后又作了修订的文件,需要重新运行 git add 把最新版本重新暂存起来)

git commit -m 'message' : 提交文件到本地仓库 备注信息message

git commit : 会启动一个vim编辑器填写提交说明信息

git commit -a -m "test" :不使用暂存区,将所有修改提交

git commit --amend : 会将暂存区中的文件提交,如果自上次提交以来你还未做任何修改(例如,在上次提交后马上执行了此命令),那么快照会保持不变,所修改的只是提交信息。

例如,你提交后发现忘记了暂存某些需要的修改,可以像下面这样操作:

$ git commit -m 'initial commit'

$ git add forgotten_file

$ git commit --amend

git clone https://gitee.com/dreamyy/zheng.git :克隆远程仓库里面的项目

git status :显示文件当前状态 git status -s : 紧凑形式输出

echo 'My Project' > README : 创建README文件

vim .gitignore :创建.gitignore文件 官网所给不同语言的规范:https://github.com/github/gitignore

文件 .gitignore 的格式规范如下:

* 所有空行或者以 # 开头的行都会被 Git 忽略。

* 可以使用标准的 glob 模式匹配。

* 匹配模式可以以(/)开头防止递归。

* 匹配模式可以以(/)结尾指定目录。

* 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。

所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。 星号(*)匹配零个或多个任意字符;[abc] 匹配任何一个列在方括号中的字符(这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c);问号(?)只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的数字)。 使用两个星号(*) 表示匹配任意中间目录,比如`a/**/z` 可以匹配 a/z, a/b/z 或 `a/b/c/z`等。

git diff :查看尚未暂存的文件更新了哪些部分(注意,git diff 本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动)

git diff --staged :查看已暂存的将要添加到下次提交里的内容

git rm file_name : 删除git跟踪的文件,注意,本地也会删除!! git rm --cached file_name : 使文件脱离git追踪,本地不删除

命令后面可以列出文件或者目录的名字,也可以使用 glob 模式

注意到星号 * 之前的反斜杠 \, 因为 Git 有它自己的文件模式扩展匹配方式,所以我们不用 shell 来帮忙展开。 此命令删除 log/ 目录下扩展名为 .log 的所有文件。 类似的比如:

$ git rm \*~

该命令为删除以 ~ 结尾的所有文件。

git log :查看提交历史

参数:一个常用的选项是 -p,用来显示每次提交的内容差异。 你也可以加上 -2 来仅显示最近两次提交。

每次交的简略的统计信息,你可以使用 --stat 选项

--pretty 这个选项可以指定使用不同于默认格式的方式展示提交历史。

--oneline 将每个提交放在一行显示,查看的提交数很大时非常有用。 另外还有 short,full 和 fuller 可以用,展示的信息或多或少有些不同

详情:https://git-scm.com/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E6%9F%A5%E7%9C%8B%E6%8F%90%E4%BA%A4%E5%8E%86%E5%8F%B2

git reset HEAD file_name : 取消暂存文件,提交时不提交该文件(在提交时不使用-a参数的情况下)

详情:https://git-scm.com/book/zh/v2/Git-工具-重置揭密#r_git_reset

git checkout -- file_name :此命令非常危险,会撤销你对该文件的所有修改!

远程仓库相关:

git remote : 查看远程仓库 -v参数:显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL。

git remote add <shortname> <url> :(git remote add lyy http:....)添加远程仓库 后,现在你可以在命令行中使用字符串 <shortname>来代替整个 URL

git fetch remote_name ; 从远程数据库中拉取 例如:git fetch lyy;

如果你使用 clone 命令克隆了一个仓库,命令会自动将其添加为远程仓库并默认以 “origin” 为简写。 所以,git fetch origin 会抓取克隆(或上一次抓取)后新推送的所有工作。 必须注意 git fetch 命令会将数据拉取到你的本地仓库 - 它并不会自动合并或修改你当前的工作。 当准备好时你必须手动将其合并入你的工作。

git push [remote-name] [branch-name] : 推送项目

$ git push origin master : 将 master 分支推送到 origin 服务器时(再次说明,克隆时通常会自动帮你设置好那两个名字),那么运行这个命令就可以将你所做的备份到服务器

注意:只有当你有所克隆服务器的写入权限,并且之前没有人推送过时,这条命令才能生效。 当你和其他人在同一时间克隆,他们先推送到上游然后你再推送到上游,你的推送就会毫无疑问地被拒绝。 你必须先将他们的工作拉取下来并将其合并进你的工作后才能推送。

git tag :列出已有的标签

git tag -a v1.4 -m 'my version 1.4' :(附注标签)为最后一次提交打标签,名字:v1.4 信息: my version 1.4

git show v1.4 :显示该标签的所有信息(包括commit信息)

git tag v1.5 :(轻量标签) 轻量标签本质上是将提交校验和存储到一个文件中 - 没有保存任何其他信息。如果在标签上运行 git show,你不会看到额外的标签信息。 命令只会显示出提交信息

git tag -a v1.2 9fceb02 :(后期打标签 )假设在 v1.2 时你忘记给项目打标签,也就是在 “updated rakefile” 提交。 你可以在之后补上标签。 要在那个提交上打标签,你需要在命令的末尾指定提交的校验和(或部分校验和)

git push origin [tagname] :git push 命令并不会传送标签到远程仓库服务器上。 在创建完标签后你必须显式地推送标签到共享服务器上。 这个过程就像共享远程分支一样 - 你可以运行 git push origin [tagname]。

alias (别名)

在创建你认为应该存在的命令时这个技术会很有用。 例如,为了解决取消暂存文件的易用性问题,可以向 Git 中添加你自己的取消暂存别名:

$ git config --global alias.unstage 'reset HEAD --'

这会使下面的两个命令等价:

$ git unstage fileA

$ git reset HEAD -- fileA

分支相关

git branch :获得所有分支列表,前面带”*“的为当前指向的分支

git branch -v :显示每个分支的最后一次提交

--merged 与 --no-merged 这两个有用的选项可以过滤这个列表中已经合并或尚未合并到当前分支的分支。

git branch lyy :创建一个分支,但不会自动切换到该分支

git checkout -b lyy2 :创建一个分支使用-b参数,并自动切换的到该分支

git log --oneline --decorate :查看各个分支当前所指的对象

--online是一个提交数据显示在一行的意思

-- decorate参数:是所用参数

不使用decorate 参数,默认也显示。。。

git checkout lyy : 切换到该分支

git checkout master - 》 git merge hotfix :两个命令,第一个命令是切换到你想要合并到的哪个分支,第二个命令将hotfix分支合并到第一个命令所切换到的分支中。注意:并不是非要合并到master分支,合并到任何分支都可以。

git branch -d liyy2 :使用-d参数删除lyy2分支。 注意:如果当前所处的分支为所删除的分支,则不可以删除,需切换到别的分支。

-D :使用该参数代替 -d参数,表示强制删除该分支,即使该分支有未合并的修改。

推送

git push (remote) (branch) 例如:git push origin lyy(将lyy分支推送到origin所代表的远程服务器中.

git push origin lyy:lyy2 来将本地的 lyy分支推送到远程仓库上的 lyy2分支。

跟踪分支

git checkout --track origin/serverfix :为origin/serverfix创建一个本地跟踪分支serverfix , 现在,本地分支 serverfix会自动从 origin/serverfix 拉取。

git checkout -b lyymas lyy/master :使用-b参数,创建一个不同名字的跟踪分支。

git branch -vv : 查看设置的所有跟踪分支

拉取

git pull : 在服务器上拉取对应分支的数据(根据本地所处分支所跟踪的分支)。

git push origin --delete lyy : 在远程服务器origin上删除lyy分支。 注意:Git 服务器通常会保留数据一段时间直到垃圾回收运行,所以如果不小心删除掉了,通常是很容易恢复的。

  • 其他
    • Git 作为一个系统,是以它的一般操作来管理并操纵(HEAD\index\Working Directory)三棵树的
      • HEAD 
        • HEAD 是当前分支引用的指针,它总是指向该分支上的最后一次提交。 这表示 HEAD 将是下一次提交的父结点。 通常,理解 HEAD 的最简方式,就是将它看做 你的上一次提交的快照。
      • index
        • 索引是你的 预期的下一次提交。 我们也会将这个概念引用为 Git 的 “暂存区域”,这就是当你运行 git commit 时 Git 看起来的样子。
        • Git 将上一次检出到工作目录中的所有文件填充到索引区,它们看起来就像最初被检出时的样子。 之后你会将其中一些文件替换为新版本,接着通过 git commit 将它们转换为树来用作新的提交。
      • Working Directory
        • 最后,你就有了自己的工作目录。 另外两棵树以一种高效但并不直观的方式,将它们的内容存储在 .git 文件夹中。 工作目录会将它们解包为实际的文件以便编辑。 你可以把工作目录当做 沙盒。在你将修改提交到暂存区并记录到历史之前,可以随意更改。
    • 打标签
      • 像其他版本控制系统(VCS)一样,Git 可以给历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点(v1.0 等等)。
      • Git 使用两种主要类型的标签:轻量标签(lightweight)与附注标签(annotated)。
      • 轻量标签很像一个不会改变的分支 - 它只是一个特定提交的引用。
      • 附注标签是存储在 Git 数据库中的一个完整对象。 它们是可以被校验的;其中包含打标签者的名字、电子邮件地址、日期时间;还有一个标签信息;并且可以使用 GNU Privacy Guard (GPG)签名与验证。 通常建议创建附注标签,这样你可以拥有以上所有信息;但是如果你只是想用一个临时的标签,或者因为某些原因不想要保存那些信息,轻量标签也是可用的。
    • git分支案例
    • 分支新建与合并的例子
      • 实际工作中你可能会用到类似的工作流。 你将经历如下步骤:
        • 1. 开发某个网站。
        • 2. 为实现某个新的需求,创建一个分支。
        • 3. 在这个分支上开展工作。
      • 正在此时,你突然接到一个电话说有个很严重的问题需要紧急修补。 你将按照如下方式来处理:
        • 1. 切换到你的线上分支(production branch)。
        • 2. 为这个紧急任务新建一个分支,并在其中修复它。
        • 3. 在测试通过之后,切换回线上分支,然后合并这个修补分支,最后将改动推送到线上分支。
        • 4. 切换回你最初工作的分支上,继续工作。
    • 分支三方合并案例
    • 分支开发工作流建议分支
    • 长期分支
    • 因为 Git 使用简单的三方合并,所以就算在一段较长的时间内,反复把一个分支合并入另一个分支,也不是什么难事。 也就是说,在整个项目开发周期的不同阶段,你可以同时拥有多个开放的分支;你可以定期地把某些特性分支合并入其他分支中。
    • 许多使用 Git 的开发者都喜欢使用这种方式来工作,比如只在 master 分支上保留完全稳定的代码——有可能仅仅是已经发布或即将发布的代码。 他们还有一些名为 develop 或者 next 的平行分支,被用来做后续开发或者测试稳定性——这些分支不必保持绝对稳定,但是一旦达到稳定状态,它们就可以被合并入 master 分支了。 这样,在确保这些已完成的特性分支(短期分支,比如之前的 iss53 分支)能够通过所有测试,并且不会引入更多 bug 之后,就可以合并入主干分支中,等待下一次的发布。
    • 特性分支
    • 特性分支对任何规模的项目都适用。 特性分支是一种短期分支,它被用来实现单一特性或其相关工作。
    • 服务器上的 Git - GitLab
      • 虽然 GitWeb 相当简单。 但如果你正在寻找一个更现代,功能更全的 Git 服务器,这里有几个开源的解决方案可供你选择安装。 因为 GitLab 是其中最出名的一个,我们将它作为示例并讨论它的安装和使用。 这比 GitWeb 要复杂的多并且需要更多的维护,但它的确是一个功能更全的选择。
      • 安装使用详情:https://git-scm.com/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-GitLab
      • 如果不想设立自己的 Git 服务器,你可以选择将你的 Git 项目托管到一个外部专业的托管网站。 这带来了一些好处:一个托管网站可以用来快速建立并开始项目,且无需进行服务器维护和监控工作。 即使你在内部设立并且运行了自己的服务器,你仍然可以把你的开源代码托管在公共托管网站 - 这通常更有助于开源社区来发现和帮助你。
    • 其他分布式git ,git工具 ,自定义git ,内部原理等详细信息,请移步Git官网:https://git-scm.com/book/zh/v2
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-07-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
代码托管
CODING 代码托管(CODING Code Repositories,CODING-CR)是为开发者打造的云端便捷代码管理工具,旨在为更多的开发者带去便捷、高效的开发体验,全面支持 Git/SVN 代码托管,包括代码评审、分支管理、超大仓库等功能。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档