52. 高级/将来的主题
最后更新于:2022-04-01 11:07:45
这里是一些你可能想要自己研究的主题:
* 还原提交的更改
* 跨操作系统行尾处理
* 远程服务器
* 协议
* SSH 设置
* 远程分支管理
* 查找有 Bug 的提交 (git bisect)
* 工作流
* 非命令行工具 (gitx、gitk、magit)
* 处理 GitHub
51. 共享仓库
最后更新于:2022-04-01 11:07:43
## 目的
> 学习通过 WiFi 共享仓库。
看看你的邻居是否在运行 `git daemon`。交换 IP 地址,并看看 是否能够从其他人的仓库拉下更改。
> 注意:gitjour gem 在共享 ad-hoc 仓库时真的有用。
50. 托管你的 Git 仓库
最后更新于:2022-04-01 11:07:40
## 目的
> 学习如何设置 Git 服务器以共享仓库。
有很多方式来通过网络共享 Git 仓库。此处是“急就章”方式。
### 启动 Git 服务器
~~~
# (From the work directory)
$ git daemon --verbose --export-all --base-path=.
~~~
现在,在分开的终端窗口中,转到你的工作目录。
~~~
# (From the work directory)
$ git clone git://localhost/hello.git network_hello
$ cd network_hello
$ ls
~~~
你应当看到 hello 项目的拷贝。
### 推送到 Git daemon
如果你想要推送到 Git daemon 仓库,添加 `--enable=receive-pack` 到 `git daemon` 命令。小心,因为此服务器没有授权,任何人 都能推送到你的仓库。
49. 拉下共享的更改
最后更新于:2022-04-01 11:07:38
## 目的
> 学习如何从共享的仓库拉下更改。
迅速跳过克隆仓库,且让我们拉下刚才推送到共享仓库的更 改。
~~~
$ cd ../cloned_hello
~~~
注意:现在在 cloned_hello 仓库中。
继续处理……
~~~
$ git remote add shared ../hello.git
$ git branch --track shared master
$ git pull shared master
$ cat README
~~~
48. 推送更改
最后更新于:2022-04-01 11:07:36
## 目的
> 学习如何将更改推到远程仓库。
因为裸仓库通常共享在某种网络服务器上,所以一般很难转 到仓库中并拉下更改。因此,我们需要将更改推到其它的仓 库中。
让我们通过创建更改来开始推送。编辑 README 并提交它。
~~~
This is the Hello World example from the git tutorial.
(Changed in the original and pushed to shared)
~~~
~~~
$ git checkout master
$ git add README
$ git commit -m "Added shared comment to readme"
~~~
现在推送更改到共享的仓库。
~~~
$ git push shared master
~~~
`shared` 是接收我们推送更改的仓库名称。(记住,在上一实 验中我们已经将它添加为远程分支。)
~~~
$ git push shared master
To ../hello.git
2e4c559..3923dd5 master -> master
~~~
注意:我们必须明确地指定接收推送的分支名称 master。它可 以设置为自动化,但我从未记住实现的命令。选择“Git Remote Branch” gem 更易管理远程分支。
47. 添加远程仓库
最后更新于:2022-04-01 11:07:33
## 目的
> 将裸仓库作为远程仓库添加到我们的原始仓库中。
让我们添加 hello.git 到我们的原始仓库。
~~~
$ cd hello
$ git remote add shared ../hello.git
~~~
注意:现在在 hello 仓库中。
46. 裸仓库
最后更新于:2022-04-01 11:07:31
## 目的
> 学习如何创建裸仓库。
裸仓库(没有工作目录)通常用于共享。
### 创建裸仓库
~~~
$ cd ..
$ git clone --bare hello hello.git
$ ls hello.git
~~~
注意:现在在工作目录中。
~~~
$ git clone --bare hello hello.git
Cloning into bare repository hello.git...
done.
$ ls hello.git
HEAD
config
description
hooks
info
objects
packed-refs
refs
~~~
结尾带 `.git` 的仓库习惯约定是裸仓库。我们可以看到在 hello.git 仓库中没有工作目录。实际上,除了非裸仓库的 .git 目录外什么也没有。
45. 添加跟踪的分支
最后更新于:2022-04-01 11:07:29
## 目的
> 学习如何添加跟踪远程分支的本地分支。
包含 `remotes/origin` 开头的分支是来自原始仓库的分支。注意 你没有叫 greet 的分支,但它知道原始仓库有 greet 分支。
### 添加跟踪远程分支的本地分支
~~~
$ git branch --track greet origin/greet
$ git branch -a
$ git hist --max-count=2
~~~
~~~
$ git branch --track greet origin/greet
Branch greet set up to track remote branch greet from origin.
$ git branch -a
greet
* master
remotes/origin/HEAD -> origin/master
remotes/origin/greet
remotes/origin/master
$ git hist --max-count=2
* 2e4c559 2013-04-13 | Changed README in original repo (HEAD, origin/master, origin/HEAD, master) [Jim Weirich]
* 2fae0b2 2013-04-13 | Updated Rakefile (origin/greet, greet) [Jim Weirich]
~~~
我们现在可以在分支列表和日志中看到 greet 分支。
44. 拉下更改
最后更新于:2022-04-01 11:07:27
## 目的
> 学习 `git pull` 等价于 `git fetch` 和 `git merge`。
### 讨论
我们不会创建另外的更改过程并再次拉下它,而是做你想要 知道的做法:
~~~
$ git pull
~~~
等价于以下两步:
~~~
$ git fetch
$ git merge origin/master
~~~
43. 合并拉下的更改
最后更新于:2022-04-01 11:07:24
## 目的
> 学习将拉下的更改合并到当前分支及工作目录。
### 将取得的更改合并到本地 master
~~~
$ git merge origin/master
~~~
~~~
$ git merge origin/master
Updating 2fae0b2..2e4c559
Fast-forward
README | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
~~~
### 再次检查 README
我们应当看到现在更改了。
~~~
$ cat README
~~~
~~~
$ cat README
This is the Hello World example from the git tutorial.
(changed in original)
~~~
这些是更改。即使 `git fetch` 不合并更改,然而我们仍然可以 手动从远程仓库合并更改。
### 下一步
接下来让我们看看将 `fetch` 和 `merge` 组合成单一命令。
42. 取得更改
最后更新于:2022-04-01 11:07:22
## 目的
> 学习如何从远程仓库拉下更改。
~~~
$ cd ../cloned_hello
$ git fetch
$ git hist --all
~~~
注意:现在在 cloned_hello 仓库中。
~~~
$ git fetch
From /Users/jim/working/git/git_immersion/auto/hello
2fae0b2..2e4c559 master -> origin/master
$ git hist --all
* 2e4c559 2013-04-13 | Changed README in original repo (origin/master, origin/HEAD) [Jim Weirich]
* 2fae0b2 2013-04-13 | Updated Rakefile (HEAD, origin/greet, master) [Jim Weirich]
* 1c23048 2013-04-13 | Hello uses Greeter [Jim Weirich]
* 62d7ce0 2013-04-13 | Added greeter class [Jim Weirich]
* b59a8c2 2013-04-13 | Added README [Jim Weirich]
* 96ee164 2013-04-13 | Added a Rakefile. [Jim Weirich]
* 0f36766 2013-04-13 | Moved hello.rb to lib [Jim Weirich]
* eb30103 2013-04-13 | Add an author/email comment [Jim Weirich]
* 1f7ec5e 2013-04-13 | Added a comment (v1) [Jim Weirich]
* 582495a 2013-04-13 | Added a default value (v1-beta) [Jim Weirich]
* 323e28d 2013-04-13 | Using ARGV [Jim Weirich]
* 9416416 2013-04-13 | First Commit [Jim Weirich]
~~~
在此刻,仓库具有来自原始仓库的全部提交,但它并没有整 合到克隆仓库的本地分支中。
在上面的历史中找到“Changed README in original repo”。 注意提交包括“origin/master”和“origin/HEAD”。
现在看看“Updated Rakefile”提交。你将看到本地 master 分支指到了此提交,并非我们取得的新提交。
`git fetch` 命令的结果将从远程仓库取得新的提交,但它 不会将这些提交合并到本地分支中。
### 检查 README
我们可以验证克隆的 README 没有被更改。
~~~
$ cat README
~~~
~~~
$ cat README
This is the Hello World example from the git tutorial.
~~~
看,没有更改。
41. 更改原始仓库
最后更新于:2022-04-01 11:07:20
## 目的
> 对原始仓库做些更改以便我们可以尝试拉下更改。
### 在原始的 hello 仓库中做更改
~~~
$ cd ../hello
# (You should be in the original hello repository now)
~~~
注意:现在在 hello 仓库中。
对 README 做下列更改:
~~~
This is the Hello World example from the git tutorial.
(changed in original)
~~~
现在添加并提交此更改。
~~~
$ git add README
$ git commit -m "Changed README in original repo"
~~~
### 下一步
原始的仓库现在有克隆版本中所没有的更改。接下来我们将 拉下这些更改到克隆的仓库中。
40. 远程分支
最后更新于:2022-04-01 11:07:18
## 目的
> 学习有关本地与远程分支的内容。
让我们看看在克隆的仓库中可用的分支。
~~~
$ git branch
~~~
~~~
$ git branch
* master
~~~
就是这样,只有 master 分支被列出来了。greet 分支在哪儿? `git branch` 命令默认只会列出本地分支。
### 列出远程分支
试试执行以下命令来看全部分支:
~~~
$ git branch -a
~~~
~~~
$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/greet
remotes/origin/master
~~~
Git 具有原始仓库的全部提交,但在远程仓库中的分支不会作 为本地分支。如果我们想要 greet 分支,我们需要自行创建 它。一会儿我们将看看如何做到。
39. 何为 Origin?
最后更新于:2022-04-01 11:07:15
## 目的
> 学习有关命名远程仓库的内容。
~~~
$ git remote
~~~
~~~
$ git remote
origin
~~~
我们看到克隆的仓库知道远程仓库名为 origin。让我们看看是 否能获得有关 origin 的更多信息:
~~~
$ git remote show origin
~~~
~~~
$ git remote show origin
* remote origin
Fetch URL: /Users/jim/working/git/git_immersion/auto/hello
Push URL: /Users/jim/working/git/git_immersion/auto/hello
HEAD branch (remote HEAD is ambiguous, may be one of the following):
greet
master
Remote branches:
greet tracked
master tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)
~~~
现在我们看到远程仓库“origin”简直就是原始的 hello 仓库。 远程仓库典型地存在于可能是中央服务器的独立机器上。正如 我们可以在此处看到的,它们可以指到同一机器上的仓库。关 于名称“origin”没有什么特别的,对于主中央仓库(如果有的 话)使用名称“origin”只是习惯的约定而已。
38. 回顾克隆的仓库
最后更新于:2022-04-01 11:07:13
## 目的
> 学习远程仓库上有关分支的内容。
### 查看克隆的仓库
让我们看一看克隆的仓库。
~~~
$ cd cloned_hello
$ ls
~~~
~~~
$ cd cloned_hello
$ ls
README
Rakefile
lib
~~~
你应当看到原始仓库的顶层目录中所有文件的列表 (README、 Rakefile 及 lib)。
### 回顾仓库历史
~~~
$ git hist --all
~~~
~~~
$ git hist --all
* 2fae0b2 2013-04-13 | Updated Rakefile (HEAD, origin/master, origin/greet, origin/HEAD, master) [Jim Weirich]
* 1c23048 2013-04-13 | Hello uses Greeter [Jim Weirich]
* 62d7ce0 2013-04-13 | Added greeter class [Jim Weirich]
* b59a8c2 2013-04-13 | Added README [Jim Weirich]
* 96ee164 2013-04-13 | Added a Rakefile. [Jim Weirich]
* 0f36766 2013-04-13 | Moved hello.rb to lib [Jim Weirich]
* eb30103 2013-04-13 | Add an author/email comment [Jim Weirich]
* 1f7ec5e 2013-04-13 | Added a comment (v1) [Jim Weirich]
* 582495a 2013-04-13 | Added a default value (v1-beta) [Jim Weirich]
* 323e28d 2013-04-13 | Using ARGV [Jim Weirich]
* 9416416 2013-04-13 | First Commit [Jim Weirich]
~~~
现在你应当看到新仓库的全部提交列表,而且它或多或少会 匹配原始仓库的提交历史。仅有的差异体现在分支名称上。
### 远程分支
你应当在历史列表中看到 master 分支 (孤单的 HEAD)。而且你也 将有许多奇怪的分支名称 (origin/master、origin/greet 及 origin/HEAD )。我们一会儿将讨论它们。
37. 克隆仓库
最后更新于:2022-04-01 11:07:11
## 目的
> 学习如何创建仓库的拷贝。
### 转到工作目录
转到工作目录并创建 hello 仓库的克隆。
~~~
$ cd ..
$ pwd
$ ls
~~~
注意:现在在工作目录中。
~~~
$ cd ..
$ pwd
/Users/jim/working/git/git_immersion/auto
$ ls
hello
~~~
此刻你应当在你的工作目录,且有名为“hello”的单一仓库。
### 创建 hello 仓库的克隆
让我们创建仓库的克隆。
~~~
$ git clone hello cloned_hello
$ ls
~~~
~~~
$ git clone hello cloned_hello
Cloning into cloned_hello...
done.
$ ls
cloned_hello
hello
~~~
在你的工作目录中现在应当有两个仓库:原始的“hello”仓库 和新克隆的“cloned_hello”仓库。
36. 多个仓库
最后更新于:2022-04-01 11:07:09
直到此时我们处理的都是单一 Git 仓库。然而,Git 也擅长处 理多个仓库。这些扩展的仓库也许存储在本地,也许通过网络 连接访问。
在下一节我们将创建名为“cloned_hello”的新仓库。我们将展 示如何将更改从一个仓库迁移到另一个仓库,以及如何处理两个 仓库之间出现的冲突。
![clone](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-07-28_55b706d4cb5e1.png)
现在,我们将处理本地仓库(如:存储在本机硬盘上的仓库), 然而从本节学到的多数内容同样可以应用到多个仓库,无论它们 是存储在本地,还是通过网络远程访问。
注意:我们将对仓库的拷贝做更改,确认在后续实验中的每个 步骤你在哪个仓库。
35. 合并回 master
最后更新于:2022-04-01 11:07:06
## 目的
> 我们已经保持 greet 分支与 master 最新(通过变基),现在让 我们合并 greet 中的更改回到 master 分支。
### 合并 greet 到 master 中
~~~
$ git checkout master
$ git merge greet
~~~
~~~
$ git checkout master
Switched to branch 'master'
$
$ git merge greet
Updating b59a8c2..2fae0b2
Fast-forward
Rakefile | 2 +-
lib/greeter.rb | 8 ++++++++
lib/hello.rb | 6 ++++--
3 files changed, 13 insertions(+), 3 deletions(-)
create mode 100644 lib/greeter.rb
~~~
因为 master 的头是 greet 分支头的直接祖先,所以 Git 可以做 快进合并。当快进时,分支指针简单地前进到与 greet 分支相同 的提交处。
在快进合并中从来不会冲突。
### 回顾日志
~~~
$ git hist
~~~
~~~
$ git hist
* 2fae0b2 2013-04-13 | Updated Rakefile (HEAD, master, greet) [Jim Weirich]
* 1c23048 2013-04-13 | Hello uses Greeter [Jim Weirich]
* 62d7ce0 2013-04-13 | Added greeter class [Jim Weirich]
* b59a8c2 2013-04-13 | Added README [Jim Weirich]
* 96ee164 2013-04-13 | Added a Rakefile. [Jim Weirich]
* 0f36766 2013-04-13 | Moved hello.rb to lib [Jim Weirich]
* eb30103 2013-04-13 | Add an author/email comment [Jim Weirich]
* 1f7ec5e 2013-04-13 | Added a comment (v1) [Jim Weirich]
* 582495a 2013-04-13 | Added a default value (v1-beta) [Jim Weirich]
* 323e28d 2013-04-13 | Using ARGV [Jim Weirich]
* 9416416 2013-04-13 | First Commit [Jim Weirich]
~~~
greet 和 master 分支现在相同了。
34. 变基
最后更新于:2022-04-01 11:07:04
## 目的
> 使用 `rebase` 命令代替 `merge` 命令。
好,我们回到了第一次合并前的时间点,并且我们想要将 master 中的更改集成到 greet 分支。
这次我们将使用 `rebase` 命令代替 `merge` 命令来从 master 分支中引入更改。
~~~
$ git checkout greet
$ git rebase master
$ git hist
~~~
~~~
$ go greet
Switched to branch 'greet'
$
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added Greeter class
Applying: hello uses Greeter
Applying: updated Rakefile
$
$ git hist
* 2fae0b2 2013-04-13 | Updated Rakefile (HEAD, greet) [Jim Weirich]
* 1c23048 2013-04-13 | Hello uses Greeter [Jim Weirich]
* 62d7ce0 2013-04-13 | Added greeter class [Jim Weirich]
* b59a8c2 2013-04-13 | Added README (master) [Jim Weirich]
* 96ee164 2013-04-13 | Added a Rakefile. [Jim Weirich]
* 0f36766 2013-04-13 | Moved hello.rb to lib [Jim Weirich]
* eb30103 2013-04-13 | Add an author/email comment [Jim Weirich]
* 1f7ec5e 2013-04-13 | Added a comment (v1) [Jim Weirich]
* 582495a 2013-04-13 | Added a default value (v1-beta) [Jim Weirich]
* 323e28d 2013-04-13 | Using ARGV [Jim Weirich]
* 9416416 2013-04-13 | First Commit [Jim Weirich]
~~~
### 合并 VS 变基
变基的最终结果与合并很相似。greet 分支现在包含它的全部 更改以及来自 master 分支中的所有更改。然而,提交树却十 分不同。greet 分支的提交树已被重写,以致 master 分支成 为了其提交历史的一部分。这使提交链更加线性,且更易阅读。
### 何时变基,何时合并?
不要使用变基……
如果是公开且与其他人共享的分支,那么重写公开的共享分支 将会搞砸团队中的其他会员。
要是提交分支的精确历史重要(因为变基将重写提交历史)。
根据上述准则,我会针对短期生命的本地分支使用变基,而对 公开仓库的分支使用合并。
33. 重置 master 分支
最后更新于:2022-04-01 11:07:02
## 目的
> 重置 master 分支到冲突提交前的地方。
### 重置 master 分支
当我们添加交互模式到 master 分支时,我们所做的更改与 greet 分支中的更改冲突了。让我们倒回 master 分支中冲突更改前的地 方。这允许我们来演示变基命令而不必担心冲突。
~~~
$ git checkout master
$ git hist
~~~
~~~
$ git hist
* 05f32c0 2013-04-13 | Made interactive (HEAD, master) [Jim Weirich]
* b59a8c2 2013-04-13 | Added README [Jim Weirich]
* 96ee164 2013-04-13 | Added a Rakefile. [Jim Weirich]
* 0f36766 2013-04-13 | Moved hello.rb to lib [Jim Weirich]
* eb30103 2013-04-13 | Add an author/email comment [Jim Weirich]
* 1f7ec5e 2013-04-13 | Added a comment (v1) [Jim Weirich]
* 582495a 2013-04-13 | Added a default value (v1-beta) [Jim Weirich]
* 323e28d 2013-04-13 | Using ARGV [Jim Weirich]
* 9416416 2013-04-13 | First Commit [Jim Weirich]
~~~
“Added README”是冲突的交互模式之前的提交。我们将重置 master 分支到“Added README”提交处。
~~~
$ git reset --hard <hash>
$ git hist --all
~~~
回顾下日志,应当看到仓库已经回到我们合并之前的时间点。
~~~
$ git hist --all
* b59a8c2 2013-04-13 | Added README (HEAD, master) [Jim Weirich]
| * 28917a4 2013-04-13 | Updated Rakefile (greet) [Jim Weirich]
| * 4dac415 2013-04-13 | Hello uses Greeter [Jim Weirich]
| * 39347b3 2013-04-13 | Added greeter class [Jim Weirich]
|/
* 96ee164 2013-04-13 | Added a Rakefile. [Jim Weirich]
* 0f36766 2013-04-13 | Moved hello.rb to lib [Jim Weirich]
* eb30103 2013-04-13 | Add an author/email comment [Jim Weirich]
* 1f7ec5e 2013-04-13 | Added a comment (v1) [Jim Weirich]
* 582495a 2013-04-13 | Added a default value (v1-beta) [Jim Weirich]
* 323e28d 2013-04-13 | Using ARGV [Jim Weirich]
* 9416416 2013-04-13 | First Commit [Jim Weirich]
~~~