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] ~~~
';