我知道编辑这个网站吗?

Git 研讨会

这些是 2011 年 8 月 3 日在 Max-Planck Institute of molecular Cell Biology and Genetics 举行的 Git 研讨会的笔记。

什么是版本控制系统,我为什么要关心?

版本控制系统是一个保存项目多个修订版本的数据库。修订版包括

  • 文件名和内容(不包括生成的文件)及其目录结构
  • 作者
  • 提交者
  • 作者日期
  • 提交日期
  • 描述(提交消息)导致此修订的更改内容,通常分为第一行(主题)和更详细的其余部分(正文
  • 零个、一个或多个指向当前修订版本之前的修订版本的指针

在 Git 中,提交 指的是修订。

版本控制通常有助于:

  • 轻松备份
  • 轻松检索特定修订
  • 文档(谁做了什么、何时以及为什么?)
  • 文档(我该怎么做……?)
  • 轻松同步(保持最新状态,集成多个开发人员/机器之间的更改)
  • 有效地找到引入回归(又名错误)的变化

动手实践

初始设置:

  • 设置用户名:
      git config --global user.name "Howard Carter"
      git config --global user.email howard@egyptian-antiquities-service.com
    
  • 设置编辑器(如果您不喜欢 vi
      git config --global core.editor wordpad
    

    第一步:

  • 初始化存储库
      git init
    
  • 添加内容(Subversion 用户注意:git add 添加内容,而不仅仅是文件名
      git add hello-world.txt
    
  • 犯罪
    git commit
    

    注意事项:

  • 所有修改的文件应在调用 git commit 之前添加
  • 由于添加的文件已暂存以供提交,因此命令 git stagegit add 的同义词
  • 利用git status输出
  • 使用.gitignore文件
  • 添加签核(AKA S-O-B)
  • git init 创建 .git/,其中存储了所有存储库的文件
  • git config访问.git/config~/.gitconfig/etc/gitconfig

什么是差异?

在提交之前,最好先看看将要提交哪些修改。查看它们的一种模式是让 Git 显示 diff。每个修改的文件的 diff 由以下部分组成:

1.以diff --git开头的伪命令行

  1. 一行描述先前修订版,以 --- 开头
  2. 一行描述下一个修订版本,以 +++ 开头
  3. 一名或多名以@@ -<begin line>,<line count> +<begin line>,<line count>开头的帅哥
  4. 相应的行块,以空格开头,用于表示上一个版本和下一个版本中的行,减号表示仅在前一个版本中的行(删除的行),加号表示仅在下一个版本中的行(添加的行)。修改后的行将显示为已删除和已添加。

动手实践

  • 查看差异:
      git diff
    
  • 查看颜色差异:
      git diff --color
    
  • 更改颜色差异的默认值:
      git config --global diff.color auto
    

    关于 Git 数据模型的一句话(以及如何引用对象)

参见Git for computer scientists

  • 一切都是对象
  • 每个对象都有一个类型
  • 每个对象都有一个名称,该名称是通过单向函数(散列函数 SHA-1)根据类型和内容计算得出的
  • 这是一个 40 位十六进制数字
  • 每个对象都是不可变的(更改某些内容会更改名称)。
  • 普通文件被编码为 blob
  • 目录被编码为
  • 修订被编码为提交

为了便于使用,除了长名称(40 个十六进制字符,相当笨拙但精确)之外,还可以通过以下方式引用提交

  • 简称
  • HEAD
  • HEAD~<n>

动手实践

  • 检查版本历史记录
      git log
    
  • 以图形方式检查版本历史记录
      gitk
    
  • 通过差异检查版本历史记录
      git log -p
    
  • 检查最新 5 个版本的差异
      git log -p -5
    
  • 仅检查一次提交
      git show HEAD~5
    
  • 查看涉及一组特定文件/目录的所有提交
      git log README
    

    注意:为了消除开始提交和文件之间的歧义,请在提交和/或选项和文件/目录之间放置 --,例如git log HEAD -5 -- doc

什么是分支?为什么我需要它们?

分支是指向提交图的命名指针。主分支称为“main”(Subversion 的 trunk,Mercurial 的 default)。由于分支只是指针,因此很容易创建它们。

在分支上提交时会推进该指针(如果您需要无法推进的内容,则需要使用 tags)。

注意:分支名称必须简单,即不包含空格或通配符(尽管减号和下划线也可以)。

分支可用于按主题组织更改集。另请比较Fiji’s tutorial on topic branches

动手实践

  • 创建分支
      git checkout -b my-new-branch
    
  • 切换到另一个分支
      git checkout main
    
  • 查看所有(本地)分支(当前分支以星号为前缀)
      git branch
    
  • 切换回上一个分支
      git checkout @{-1}
    

    对于 Git 来说,“分布式”是什么意思?

到目前为止,存储库位于工作目录本地。但 Git 还可以与多个其他存储库同步。

通常,有一个指定的“主存储库”。如果您想从给定存储库初始化工作目录,请使用git clone

主存储库通常不需要工作目录,在这种情况下,它被称为裸存储库

动手实践

  • 克隆存储库
      git clone git://github.com/git/hello-world
    
  • 从 USB 磁盘或文件服务器克隆存储库
      git clone /path/to/hello-world
    
  • 在文件服务器上设置主存储库
      git init --bare --shared=group /path/to/fileserver/my.git
    

    Git 的合并概念(这个“索引”到底是什么?)

当与其他人或主题分支一起工作时,更改(包括其完整的提交历史记录)需要集成到另一个分支中,通常是main。这种集成称为合并

为了执行合并,文件版本被放入暂存区域(索引),并且所有不重叠的更改都会自动解决。重叠(读作:矛盾)的更改未得到解决,而是标记为合并冲突

请参阅斐济页面 Git Conflicts,了解如何解决合并冲突的详细说明。

动手实践

  • 初始化并提交一个文件,例如hello.txt
      echo Hello > hello.txt
      git add hello.txt
      git commit -m initial
    
  • 初始化一个新分支并修改hello.txt
      git checkout -b tut-anch-amun
      echo Boooh > hello.txt
      git add hello.txt
      git commit -m "On branch"
    
  • 切换回旧分支,修改hello.txt
      git checkout @{-1}
      echo Hi > hello.txt
      git add hello.txt
      git commit -m "On original branch"
    
  • 合并
      git merge tut-anch-amun
    

    什么是转发日志?他们能如何帮助我?

我们之前查看了提交历史记录。但每个存储库都有其自己的历史;例如,昨天中午,具有特定修订的特定分支是当前分支。这存储在引用日志中(为了空间效率,引用日志不是永久可用的,而是在某个阶段被修剪)。

您可以通过将 @{<number>}@{<date>} 附加到分支名称或 HEAD 来访问引用日志。

动手实践

  • 查看五分钟前当前的修订版本
      git show HEAD@{5.minutes.ago}
    
  • 查看转发历史记录
      git log -g
    

    藏品是什么?

有时需要存储所有修改并返回到干净状态,但保持修改可访问。这是使用 stash 完成的。

注意:stash 是一个特殊的伪分支,位于 refs/stash 中。他们的历史记录在转发日志中。

动手实践

  • 进行更改并隐藏它
      echo Shalom > hello.txt
      git stash
    
  • 把它拿回来
      git stash apply
    
  • 仅存储尚未使用 git add 添加的更改
      echo Howdy > hello.txt
      git add hello.txt
      echo Hey hey > hello.txt
      git stash -k
    
  • 获取隐藏更改的列表
      git stash list
    
  • 隐藏自定义消息
      git stash save This is my description
    
  • 从存储中删除最新的更改
      git stash pop
    

    访问对象数据库的部分内容

查看提交的主要方法是使用 git show。它可以显示标签、提交、树和 blob。

要访问有关提交的更多信息,请使用参数--pretty=fuller

对于更底层的访问,请使用git cat-file

动手实践

  • 显示原始提交消息以及差异
      git show --pretty=raw HEAD
    
  • 显示提交对应的顶级树
      git show HEAD:
    
  • 显示一个斑点
      git show HEAD:Documentation/README
    
  • 对提交的低级访问
      git cat-file commit HEAD
    

    Git 中的“checkout”、“reset”有什么含义?

我们已经看到checkout可以在分支之间切换,甚至可以初始化新分支。

不幸的是,checkout也是从其他分支选择文件版本而不切换分支的命令。因此,选择的文件版本会自动添加,即为下一次提交暂存。

要取消暂存更改,可以使用 reset 命令(不带参数,它会重置 HEAD 当前知道的所有文件)。

可以进一步说服reset命令不仅重置索引(暂存区域),还重置工作目录。

动手实践

  • 从另一个分支选择文件版本
      git checkout other-branch README
    
  • 取消所有更改,即将所有文件从“待提交”状态恢复为“已修改”
      git reset
    
  • 删除所有更改(如git stash,但不存储更改)
      git reset --hard
    

    Git 的“远程存储库”概念

除了我们克隆的存储库之外,还可以使用 git remote 命令链接其他存储库。此类存储库称为“远程存储库”或简称为“远程”。

我们克隆的存储库称为 origin

与远程存储库的交互是使用

  • git fetch,远程存储库分支的本地副本,包括所有必需的对象(但要聪明地避免获取我们已经拥有的对象)和
  • git push,将远程存储库的分支更新为本地分支的状态。

远程分支的本地副本位于特定的命名空间中,refs/remotes/<name>。例如,名为 origin 的远程的 main 分支将存储在 refs/remotes/origin/main 中。如果明确的话,也可以将其称为 origin/main

注意:您需要确保不要在同一工作目录的存储库中混合两个不同的项目。 Git 会很乐意从任何地方获取到本地存储库,即使它没有意义。

注意:获取和合并有一个快捷方式:git pull。如果您从远程分支的本地副本创建新分支,您甚至可以对其进行设置,以便 git pull 无需进一步参数即可从正确的远程获取并合并正确的分支:git checkout --track origin/cool-feature

动手实践

  • 添加遥控器
      git remote add hello git://github.com/git/hello-world
    
  • 从远程获取
      git fetch hello
    
  • 列出远程分支的所有本地副本
      git branch -r
    
  • 推一个分支
      git push origin main
    
  • 推送当前分支
      git push origin HEAD
    
  • 推送到名称与本地名称不同的分支
      git push origin my-new-branch:main
    
  • 从远程存储库中删除分支
      git push --delete origin blabla-branch
    

    流行的公共存储库托管商

如果您需要公共存储库,您可以使用 http://github.com/http://code.google.com/http://sourceforge.net/http://repo.or.cz/ 以及其他一些库。通常,您拥有相当数量的存储空间,但问题是您的版本控制项目必须是开源的。

值得庆幸的是,所有上述托管服务商都支持 gitweb,这是一个用于查看历史记录的 Web 界面。

动手实践

让我们浏览http://github.com/git/hello-world并检查历史

高级主题

  • 别名

  • 重新定位

  • 采摘樱桃

  • 部分分期

  • 交互式结帐

  • 标签(简单、带注释、签名)

  • 平分

  • 责备

  • git apply

  • git diff --color-words

  • 归档

  • 脚本编写(管道/瓷器)

  • 钩子

  • 差异过滤器

  • 与svn交互

  • 与 Mercurial 交互

  • 涂抹/清洁过滤器

  • 合并驱动程序

  • 差异驱动程序

  • 重命名处理

链接