Git基本用法与GitHub仓库的初步运用


git与github的用法


本篇内容,参考了 《GitHub入门与实践》著:[日]大塚弘记 译:支鹏浩 刘斌 这里提到的主要是git,关于GitHub的部分请直接查看这本书 如有错误和建议,还请Email联系我,我会及时更新! 版权问题Email联系我,侵删~

设置姓名和邮箱地址

首先来设置使用Git时的姓名和邮箱地址。名字请用英文输入。

git config --global user.name "Firstname Lastname"
git config --global user.email "your_email@example.com"
less ~/.gitconfig # 查看设置好的用户配置,更改信息也可以直接编辑这个文件

提高命令输出的可读性

将 color.ui 设置为 auto 可以让命令的输出拥有更高的可 读性。

git config --global color.ui auto 
# “~/.gitconfig”中会增加下面一行。 [color] 
# ui = auto 
# 这样一来,各种命令的输出就会变得更容易分辨。

mac系统下查看和生成ssh key

https://www.jianshu.com/p/32b0f8f9ca8e

# step1 check 是否存在 ~/.ssh/id_rsa 与 ~/.ssh/id_rsa.pub两个文件
# step2 不存在的时候,生成一个,your_email:这里填写你在GitLab或者GitHub注册时的邮箱。
ssh-keygen -t rsa -C"hermanzhaozzzz@gmail.com"
# 后面的提示直接敲回车,一路完成。

# strout:
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/zhaohuanan/.ssh/id_rsa):
# 默认会输出到这个文件夹
/Users/zhaohuanan/.ssh/id_rsa already exists.
Overwrite (y/n)?
# 我这里覆盖一下,我也没设置密码
# stdout
Your identification has been saved in /Users/zhaohuanan/.ssh/id_rsa.
Your public key has been saved in /Users/zhaohuanan/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:kVZgG0pDKf1DD50nbkZPAmvJXQnH12CS0/rDjjbOJMM hermanzhaozzzz@gmail.com
The key's randomart image is:
……

在github储存自己的ssh keys(公开密钥)

::id_rsa 文件是私有密钥,id_rsa.pub 是公开密钥,二者是配对的:: 。 在 GitHub 中添加公开密钥,今后就可以用私有密钥进行认证了。 Sign in to GitHub · GitHub cat一下上面这个.pub文件,复制内容,打开这个链接的网页上,选择 SSH Keys 菜 单。 点击 Add SSH Key 之后。在 Title 中输入 适当的密钥名称。Key 部分粘贴 id_rsa.pub 文件里的内容。 ::完成以上设置后,就可以用手中的私人密钥与 GitHub 进行认证和 通信了。让我们来实际试一试。::

ssh -T git@github.com
The authenticity of host 'github.com (13.229.188.59)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)? 输入yes 
# 出现这个就成功了
# 如果ssh无响应,可能是knowhosts出问题了,找到~/.ssh/known_hosts 将对应ip的信息删除
Warning: Permanently added 'github.com,13.229.188.59' (RSA) to the list of known hosts.
Hi hermanzhaozzzz! You've successfully authenticated, but GitHub does not provide shell access.

github中创建仓库并clone下来

git clone https://github.com/hermanzhaozzzz/Herman-s-Blog-Origin-File.git
# 这里会要求输入 GitHub 上设置的公开密钥的密码。认证成功后, 仓库便会被 clone 至仓库名后的目录中。将想要公开的代码提交至这个 仓库再 push 到 GitHub 的仓库中,代码便会被公开。

编写代码

git status来查看当前的git状态 git add FILE来添加修改的文件FILE git add命令将文件加入暂存区(在 Index 数据结构中记录文件提交之前的状态。) 添加成功后,可以通过 git log命令查看提交日志 git push使用过add命令后,使用此命令即可推送到github的对应仓库,进行更新。 ::这样一来代码就在 GitHub 上公开了。:: 本章讲解了初次在 GitHub 建立仓库以及公开代码的流程。完成这些,各位就踏入了GitHub的世界。

公开代码的许可协议

即便在 GitHub 上公开了源代码,也不代表著作者放弃了 著作权等权利。代码的权利持有人请选择合适的许可协议。在 GitHub 上,有::修正 BSD 许可协议::、::Apache 许可协议::等多种许 可协议供人们选择,不过::大多数软件都使用 MIT 许可协议::。
MIT 许可协议具有以下特征。
被授权人权利:
被授权人有权利使用、复制、修改、合并、出版发行、散布、 再授权和 / 或贩售软件及软件的副本,及授予被供应人同等权利,唯服从以下义务。
被授权人义务:::在软件和软件的所有副本中都必须包含以上版权声明和本许可声明::。
其他重要特性:此许可协议并非属 copyleft 的自由软件许可协议条款,允许在自由及开放源代码软件或非自由软件(proprietary...software)所使用。
MIT 的内容可依照程序著作权者的需求更改内容。此亦为 MIT 与 BSD(The BSD license, 3-clause BSD license)本质上不同处。
MIT 许可协议可与其他许可协议并存。另外,MIT 条款也是自由软件基金会 (FSF)所认可的自由软件许可协议条款,与 GPL 兼容。
——MIT 许可证,Wikipedia,http://zh.wikipedia.org/,2015 年 3 月 27 日获取
详细内容请参阅原文
实 际 使 用 时, 只 需 ::将 LICENSE 文 件 加 入 仓 库, 并 在 README.md 文件中声明使用了何种许可协议即可。::
::使用没有声明许可协议的软件时,以防万一最好直接联系著作者。::

git的一些基本操作的深入学习

git init

要::使用 Git 进行版本管理,必须先初始化仓库::。 Git 是使用 git init命令进行初始化的。请实际建立一个目录并初始化仓库。

$ mkdir git-tutorial
$ cd git-tutorial
$ git init
# 已初始化空的 Git 仓库于 /Users/zhaohuanan/opt/github/git-tutorial/.git/

如果初始化成功,执行了git init命令的目录下就会生成.git目录。这个 ::.git 目录里存储着管理当前目录内容所需的仓库数据::。 在 Git 中,我们将::这个目录的内容称为“附属于该仓库的工作树”::。 ::文件的编辑等操作在工作树中进行,然后记录到仓库中,以此管理文件 的历史快照。如果想将文件恢复到原先的状态,可以从仓库中调取之前的快照,在工作树中打开。开发者可以通过这种方式获取以往的文件::。 具体操作指令我们将在后面详细解说。

git status

git status命令用于显示Git仓库的状态。这是一个十分常用的命令,请务必牢记。 $  touch README.md 此时使用git status命令,发现,这个md文件在untracked files里面,想要让文件成为git仓库的管理对象,就需要git add

git add

——向暂存区中添加文件

$ git add README.md
$ git status
# On branch master

将 README.md 文件加入暂存区后,git 果发生了变化。可以看到,README.md 文件显示在 Changes to be committed 中了。 接下来:

git commit——保存仓库的历史记录

git commit命令可以将当前::暂存区中::的文件实际保存到仓库的::历:: ::史记录中::。通过这些记录,我们就可以在工作树中::复原文件::。

记录一行提交信息

$ git commit -m "First commit"
[master (root-commit) 9f129ba] First commit 
1 file changed, 0 insertions(+), 0 deletions(-) 
create mode 100644 README.md

-m 参数后的 "First commit"称作提交信息,是对这个提交的 概述。

记述详细提交信息

刚才我们只::简洁地记述了一行提交信息::,如果::想要记述得更加详 细::,请::不加 - m::,直接执行 git com mit命令。执行后编辑器就会启 动,并显示如下结果。

#  Please enter the commit message for your changes. Lines starting 
#  with '#' will be ignored, and an empty message aborts the commit. 
#  On branch master # 
#  Initial commit 
## Changes to be committed:
# (use "git rm --cached <file>..." to unstage) #
# new file: README.md#

在::编辑器中::记述提交信息的::格式如下::。 ● 第一行:用一行文字::简述::提交的更改内容 ● 第二行:空行 ● 第三行以后:记述更改的::原因和详细内容:: 只要按照上面的格式输入,今后便可以通过确认::日志的命令或工具:: 看到这些记录。 在以 # 标为注释的Changes to be committed(要提交的更改)栏中,可以查看本次提交中包含的文件。将提交信息按格式记述完毕后,请保存并关闭编辑器,::以 # (井号)标为注释的行不必删除::。随后,刚才记述的提交信息就会被提交。

终止提交

如果在编辑器启动后想中止提交,请将提交信息留空并直接关闭编 辑器,随后提交就会被中止。

查看提交后的状态

执行完git commit命令后再来查看当前状态。

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

::当前工作树处于刚刚完成提交的最新状态,所以结果显示没有更改::。

git log——查看提交日志

git log命令可以查看以往仓库中提交的日志。包括可以查看什么人在什么时候进行了提交或合并,以及操作前后有怎样的差别。关于合并我们会在后面解说。 我们先来看看刚才的git commit命令是否被记录了。

$ git log 
commit f579a3167f39d5b4a4488662128b7f3a131a4f2d (HEAD -> master)
Author: hermanzhaozzzz <hermanzhaozzzz@gmail.com>
Date:   Mon Feb 3 10:09:23 2020 +0800
    test
(END)

如上图所示,屏幕显示了刚刚的提交操作。commit 栏旁边显示的 “9f129b......”是指向这个提交的::哈希值::。Git 的其他命令中,在指向提交时会用到这个哈希值。::Author 栏中显示我们给 Git 设置的用户名和邮箱地址::。Date 栏中显示提交执行的::日期和时间::。再往下就是该提交的::提交信息::。

只显示提交信息的第一行

如果只想让程序显示第一行简述信息,可以在 git log命令后加 上 --pretty=short。这样一来开发人员就能够更轻松地把握多个 提交。

$ git log --pretty=short 
commit 9f129bae19b2c82fb4e98cde5890e52a6c546922 Author: hirocaster <hohtsuka@gmail.com> 
First commit

只显示指定目录、文件的日志

只要在git log命令后加上目录名,便会只显示该目录下的日志。 如果加的是文件名,就会只显示与该文件相关的日志。

$ git log README.md

显示文件的改动

如果想查看提交所带来的改动,可以加上 - p参数,文件的前后差 别就会显示在提交信息之后。 $ git log -p 比如,执行下面的命令,就可以只查看 README.md 文件的提交日 志以及提交前后的差别。 $ git log -p README.md 如上所述,git log命令可以利用多种参数帮助开发者把握以往 提交的内容。不必勉强自己一次记下全部参数,每当有想查看的日志就 积极去查,慢慢就能得心应手了。

git diff——查看更改前后的差别

不妨养成这样一个好习惯:在执行 git commit命令之前,先执行git diff HEAD命令,查看本次提交与上次提交之间有什么差别,等 确认完毕后再进行提交。这里的 ::HEAD 是指向当前分支中最新一次提交 的指针::。

branch的操作

在进行::多个并行作业时,我们会用到分支::。在这类并行开发的过程 中,往往同时存在多个最新代码状态。如图 4.1 所示,::从 master 分支创 建 feature-A 分支和 fix-B 分支后,每个分支中都拥有自己的最新代码::。 ::master 分支是 Git 默认创建的分支,因此基本上所有开发都是以这个分 支为中心进行的::。 ::不同分支中,可以同时进行完全不同的作业::。等该::分支的作业完成 之后再与 master 分支合并::。 比如 feature-A 分支的作业结束后与 master 合并,如图 4.2 所示。 通过灵活运用分支,可以让多人同时高效地进行并行开发。

git branch——显示分支一览表

git branch命令可以将分支名列表显示,同时可以确认当前所在 分支。让我们来实际运行git branch命令。

$ git branch 
* master

可以看到 master 分支左侧标有“*”(星号),表示这是我们当前所 在的分支。也就是说,我们正在 master 分支下进行开发。结果中没有显示其他分支名,表示本地仓库中只存在 master 一个分支。

git checkout -b——创建、切换分支

如果想以当前的 master 分支为基础创建新的分支,我们需要用到 git checkout -b命令。

切换到 feature-A 分支并进行提交

执行下面的命令,创建名为 feature-A 的分支。

$ git checkout -b feature-A 
Switched to a new branch 'feature-A'

实际上,连续执行下面两条命令也能收到同样效果。

$ git branch feature-A
$ git checkout feature-A

创建 feature-A 分支,并将当前分支切换为 feature-A 分支。这时再 来查看分支列表,会显示我们处于 feature-A 分支下。

$ git branch 
* feature-A 
master

feature-A 分支左侧标有“*”,表示当前分支为 feature-A。 ::在这个状态下像正常开发那样修改代码、执行 git add命令并进行提交的话, 代码就会提交至 feature-A 分支。:: ::像这样不断对一个分支(例如 feature-A)进行提交的操作,我们称为“培育分支”::。

下面来实际操作一下。在 README.md 文件中添加一行。

# Git教程 
- feature-A

这里我们添加了 feature-A 这样一行字母,然后进行提交。

$  git add README.md 
$  git commit -m "Add feature-A" 
[feature-A 8a6c8b9] Add feature-A 
1 file changed, 2 insertions(+)

于是,这一行就添加到 feature-A 分支中了。

切换到 master 分支

现在我们再来看一看 master 分支有没有受到影响。首先切换至 master 分支。

$ git checkout master 
Switched to branch 'master'

然后::查看 README.md 文件,会发现 README.md 文件仍然保持 原先的状态,并没有被添加文字::。feature-A 分支的更改不会影响到 master 分支,这正是在开发中创建分支的优点。只要创建多个分支,就可以在不互相影响的情况下同时进行多个功能的开发。 像上面这样用 “ - ”( 连 字 符 ) 代替分支名 , 就可以切换至一个分支。当然,将“-”替换成 feature-A 同样可以切换到 feature-A 分支。

特性分支

Git 与 Subversion(SVN)等集中型版本管理系统不同,创建分支时不需要连接中央仓库,所以能够相对轻松地创建分支。因此,当今大部分工作流程中都用到了特性(Topic)分支。 特性分支顾名思义,是集中实现::单一特性(主题),除此之外不进 行任何作业的分支::。在日常开发中,往往会创建数个特性分支,同时::在此之外再保留一个随时可以发布软件的稳定分支::。::稳定分支的角色通常由 master 分支担当::(图 4.3)。 之前我们创建了 feature-A 分支,这一分支::主要实现 feature-A,除 feature-A 的实现之外不进行任何作业::。::即便在开发过程中发现了 BUG, 也需要再创建新的分支,在新分支中进行修正::。 ::基于特定主题的作业在特性分支中进行,主题完成后再与 master 分支合并。只要保持这样一个开发流程,就能保证 master 分支可以随时供 人查看。这样一来,其他开发者也可以放心大胆地从 master 分支创建新 的特性分支::。

主干分支

主干分支是刚才我们讲解的::特性分支的原点::,同时也是::合并的终点::。通常人们会用 ::master 分支作为主干分支::。主干分支中并没有开发到 一半的代码,可以随时供他人查看。 有时我们::需要让这个主干分支总是配置在正式环境中,有时又需要 用标签 Tag 等创建版本信息,同时管理多个版本发布。拥有多个版本发 布时,主干分支也有多个::。

git merge——合并分支

接下来,我们假设 feature-A 已经实现完毕,想要将它合并到主干分 支 master 中。首先切换到 master 分支。

$ git checkout master 
Switched to branch 'master'

然后合并 feature-A 分支。为了在历史记录中明确记录下本次分支合并,我们需要创建合并提交。::因此,在合并时加上 --no-ff参数::。

$ git merge --no-ff feature-A

随后编辑器会启动,用于录入合并提交的信息。

Merge branch 'feature-A' 
#  Please enter a commit message to explain why this merge is necessary, 
#  especially if it merges an updated upstream into a topic branch. # 
#  Lines starting with '#' will be ignored, and an empty message aborts 
#  the commit.

默认信息中已经包含了是从 feature-A 分支合并过来的相关内容,所 以可不必做任何更改。将编辑器中显示的内容保存,关闭编辑器,然后就会看到下面的结果。

Merge made by the 'recursive' strategy. 
README.md | 2 ++ 
1 file changed, 2 insertions(+)

这样一来,feature-A 分支的内容就合并到 master 分支中了。

git log --graph——以图表形式查看分支

用 git log --graph命令进行查看的话,能很清楚地看到特性 分支(feature-A)提交的内容已被合并。除此以外,特性分支的创建以 及合并也都清楚明了。 git log --graph命令可以用图表形式输出提交日志,非常直观,请大家务必记住。

更改提交的操作

git reset——回溯历史版本

通过前面学习的操作,我们已经学会如何在::实现功能后进行提交::, ::累积提交日志作为历史记录,借此不断培育一款软件::。 Git 的另一特征便是可以::灵活操作历史版本。借助分散仓库的优势, 可以在不影响其他仓库的前提下对历史版本进行操作::。 在这里,为了让各位熟悉对历史版本的操作,我们::先回溯历史版本::,创建一个名为 fix-B 的特性分支(图 4.4)。

回溯到创建 feature-A 分支前

让我们先回溯到上一节 feature-A 分支创建之前,创建一个名为 fix-B 的特性分支。 要让::仓库的 HEAD、暂存区、当前工作树回溯到指定状态,需要用到git rest --hard命令::。只要提供::目标时间点的哈希值:: ,就可以 完全恢复至该时间点的状态。事不宜迟,让我们执行下面的命令。

$ git reset --hard fd0cbf0d4a25f747230694d95cac1be72d33441d 
HEAD is now at fd0cbf0 Add index

我们已经成功回溯到特性分支(feature-A)创建之前的状态。由于 所有文件都回溯到了指定哈希值对应的时间点上,README.md 文件的 内容也恢复到了当时的状态。

创建 fix-B 分支

现在我们来创建特性分支( fix-B)。

$ git checkout -b fix-B
Switched to a new branch 'fix-B'

作为这个主题的作业内容,我们在 README.md 文件中添加一行文字。

# Git教程 
- fix-B

然后直接提交 README.md 文件。

$  git add README.md 
$  git commit -m "Fix B" 
[fix-B 4096d9e] Fix B 
1 file changed, 2 insertions(+)

现在的状态如图 4.5 所示。接下来我们的目标是图 4.6 中所示的状态,即主干分支合并 feature-A 分支的修改后,又合并了 fix-B 的修改。

推进至 feature-A 分支合并后的状态

首先恢复到 feature-A 分支合并后的状态。不妨称这一操作为“推进历史”。 git log命令只能查看以当前状态为终点的历史日志。所以这里 要使用 git reflog命令,查看当前仓库的操作日志。在日志中找出回溯历史之前的哈希值,通过git reset --hard命令恢复到回溯历 史前的状态。 首先执行git reflog命令,查看当前仓库执行过的操作的日志。 在日志中,我们可以看到 commit、checkout、reset、merge 等 Git 命 令的执行记录。 只要不进行 Git 的 GC(Garbage Collection,垃圾回收), 就可以通过日志随意调取近期的历史状态,就像给时间机器指定一个时间点,在过去未来中自由穿梭一般。 即便开发者错误执行了 Git 操作, 基本也都可以利用 git reflog命令恢复到原先的状态,所以请各位读者务必牢记本部分。 从上面数第四行表示 feature-A 特性分支合并后的状态,对应哈希值 A 为83b0b94 。我们将HEAD、暂存区、工作树恢复到这个时间点的状态。

$ git checkout master 
$ git reset --hard 83b0b94
HEAD is now at 83b0b94 Merge branch 'feature-A'

之前我们使用git reset --hard命令回溯了历史,这里又再次 通过它恢复到了回溯前的历史状态。当前的状态如图 4.7 所示。

消除冲突

现在只要合并 fix-B 分支,就可以得到我们想要的状态。让我们赶快进行合并操作。

$ git merge --no-ff fix-B
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Recorded preimage for 'README.md'
Automatic merge failed; fix conflicts and then commit the result.

这时,系统告诉我们 README.md 文件发生了冲突(Conflict)。系 统在合并 README.md 文件时,feature-A 分支更改的部分与本次想要合 并的 fix-B 分支更改的部分发生了冲突。 不解决冲突就无法完成合并,所以我们打开 README.md 文件,解 决这个冲突。

# Git教程 
<<<<<<< HEAD - feature-A 
======= 
- fix-B >>>>>>> fix-B

======= 以上的部分是当前 HEAD 的内容,以下的部分是要合并 的 fix-B 分支中的内容。我们在编辑器中将其改成想要的样子。

# Git教程
- feature-A 
- fix-B

如上所示,本次修正让 feature-A 与 fix-B 的内容并存于文件之中。 但是在实际的软件开发中,往往需要删除其中之一,所以各位在处理冲 突时,务必要仔细分析冲突部分的内容后再行修改。

提交解决后的结果

冲突解决后,执行 git add命令与 git commit命令。

$ git add README.md 
$ git commit -m "Fix conflict" 
Recorded resolution for 'README.md'. 
[master 6a97e48] Fix conflict

由于本次更改解决了冲突,所以提交信息记为 "Fix conflict"。

git commit --amend——修改提交信息

要修改上一条提交信息,可以使用git commit --amend命令。 我们将上一条提交信息记为了 "Fix conflict",但它其实是 fix-B 分 支的合并,解决合并时发生的冲突只是过程之一,这样标记实在不妥。 于是,我们要修改这条提交信息。

$ git commit --amend

执行上面的命令后,编辑器就会启动。

Fix conflict       
# Please enter the commit message for your changes. Lines starting with '#' will be ignored, and an empty message aborts the commit. 
# On branch master
# Changes to be committed: 
# (use "git reset HEAD^1 <file>..." to unstage) 
# modified: README.md

编辑器中显示的内容如上所示,其中包含之前的提交信息。请将 提交信息的部分修改为 Merge branch 'fix-B',然后保存文件,关闭编 辑器。

[master 2e7db6f] Merge branch 'fix-B'

随后会显示上面这条结果。现在执行 git log 可以看到提交日志中的相应内容也已经被修改。

git rebase -i——压缩历史

在合并特性分支之前,如果发现已提交的内容中有些许拼写错误等, 不妨提交一个修改,然后将这个修改包含到前一个提交之中,压缩成一 个历史记录。这是个会经常用到的技巧,让我们来实际操作体会一下。

创建 feature-C 分支

首先,新建一个 feature-C 特性分支。

$ git checkout -b feature-C 
Switched to a new branch 'feature-C'

作为 feature-C 的功能实现,我们在 README.md 文件中添加一行 文字,并且故意留下拼写错误,以便之后修正。

# Git教程 
- feature-A 
- fix-B
- faeture-C

提交这部分内容。这个小小的变更就没必要先执行git add命令再执行git commit命令了,我们用git commit -am 命令来一次完成这两步操作。

$ git commit -am "Add feature-C" 
[feature-C 7a34294] Add feature-C 
1 file changed, 1 insertion(+)

修正拼写错误

现在来修正刚才预留的拼写错误。请各位自行修正 README.md 文 件的内容,修正后的差别如下所示。

$ git diff
diff --git a/README.md b/README.md index ad19aba..af647fd 100644
--- a/README.md
+++ b/README.md
@@ -2,4 +2,4 @@ 
- feature-A 
- fix-B
- - faeture-C 
+ - feature-C

然后进行提交。

$ git commit -am "Fix typo" 
[feature-C 6fba227] Fix typo 
1 file changed, 1 insertion(+), 1 deletion(-)

错字漏字等失误称作 typo,所以我们将提交信息记为 " Fix typo"。 实际上,我们不希望在历史记录中看到这类提交,因为健全的历史记录 并不需要它们。如果能在最初提交之前就发现并修正这些错误,也就不 会出现这类提交了。

更改历史

因此,我们来更改历史。将 " Fix typo"修正的内容与之前一次的 提交合并,在历史记录中合并为一次完美的提交。为此,我们要用到 git rebase命令。

$ git rebase -i HEAD~2

用上述方式执行 git rebase命令,可以选定当前分支中包含 HEAD(最新提交)在内的两个最新历史记录为对象,并在编辑器中 打开。

我们将 6fba227 的 Fix typo 的历史记录压缩到 7a34294 的 Add feature-C 里。按照下图所示,将 6fba227 左侧的 pick 部分删除,改写为 fixup。

pick 7a34294 Add feature-C 
fixup 6fba227 Fix typo

保存编辑器里的内容,关闭编辑器。

[detached HEAD 51440c5] Add feature-C 
1 file changed, 1 insertion(+) 
Successfully rebased and updated refs/heads/feature-C.

系统显示 rebase 成功。也就是以下面这两个提交作为对象,将 "Fix typo"的内容合并到了上一个提交 "Add feature-C"中,改写成了一个新 的提交。 ●  7a34294 Add feature-C ●  6fba227 Fix typo 现在再查看提交日志时会发现 Add feature-C 的哈希值已经不是 7a34294 了,这证明提交已经被更改。 这样一来,Fix typo 就从历史中被抹去,也就相当于 Add feature-C 中从来没有出现过拼写错误。这算是一种良性的历史改写。

合并至master分支

feature-C 分支的使命告一段落,我们将它与 master 分支合并。

$ git checkout master 
Switched to branch 'master' 
$ git merge --no-ff feature-C
Merge made by the 'recursive' strategy. 
README.md | 1 +
1 file changed, 1 insertion(+)

master 分支整合了 feature-C 分支。开发进展顺利。

推送至远程仓库

Git 是分散型版本管理系统,但我们前面所学习的,都是针对单一 本地仓库的操作。下面,我们将开始接触远在网络另一头的远程仓库。远程仓库顾名思义,是与我们本地仓库相对独立的另一个仓库。 让我们先在 GitHub 上创建一个仓库,并将其设置为本地仓库的远程仓库。 请参考第 3 章的 3.2 节在 GitHub 上新建一个仓库。::为防止与其他仓库混淆,仓库名请与本地仓库保持一致,即 git-tutorial::。创建时请::不要 勾选 Initialize this repository with a README 选项(图 4.8)。因为一旦勾 选该选项,GitHub 一侧的仓库就会自动生成 README 文件,从创建之 初便与本地仓库失去了整合性。虽然到时也可以强制覆盖,但为防止这 一情况发生还是建议不要勾选该选项,直接点击 Create repository 创建 仓库::。

git remote add——添加远程仓库

在 GitHub 上创建的仓库路径为“git@github.com:用户名 / git-tutorial.git”。现在我们用git remote add命令将它设置 成本地仓库的远程仓库。

git remote add origin git@github.com:hermanzhaozzzz/git-tutorial.git

按照上述格式执行 git remote add命令之后,Git 会自动将 git@github.com:github-book/git-tutorial.git远程仓库的 ::名称设置为 origin(标识符)::。

git push——推送至远程仓库

推送至 master 分支

如果想将当前分支下本地仓库中的内容推送给远程仓库,需要用到 git push命令。现在::假定我们在master分支下进行操作::。 像这样执行git push命令,当前分支的内容就会被推送给::远程仓库 origin:: 的 ::master 分支::。 ::-u参数可以在推送的同时,将 origin 仓库的 master 分支设置为本地仓库当前分支的 upstream(上游)::。 ::添加了这个参数,将来运行 git pull命令从远程仓库获取内容时,本地仓库的这个分支就可 以直接从 origin 的 master 分支获取内容,省去了另外添加参数的麻烦::。 执行该操作后,当前本地仓库 master 分支的内容将会被推送到 GitHub 的远程仓库中。在 GitHub 上也可以确认远程 master 分支的内容和本地 master 分支相同。


遇到了ssh key的问题,https协议可以连接github,ssh不可以,解决方案: 在~/.ssh/下新建config文件,内容为:

Host github.com
User git
Hostname ssh.github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa
Port 443

总结一下!!上面这两节

github新建仓库,不选择加入readme.md文件 本地仓库新建,cd进入 git init git remote add origin git@github.com:hermanzhaozzzz/仓库名.git 各种操作,想要同步到github仓库 git push -u origin master


推送至 master 以外的分支

除了 master 分支之外,远程仓库也可以创建其他分支。举个例子,我们在本地仓库中创建 feature-D 分支,并将它以同名形式 push 至远程仓库。

$ git checkout -b feature-D
Switched to a new branch 'feature-D'

我们在本地仓库中创建了 feature-D 分支,现在将它 push 给远程仓 库并保持分支名称不变。

$ git push -u origin feature-D
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:github-book/git-tutorial.git 
* [new branch] feature-D -> feature-D
Branch feature-D set up to track remote branch feature-D from origin

现在,在远程仓库的 GitHub 页面就可以查看到 feature-D 分支了。

从远程仓库获取

上一节中我们把在 GitHub 上新建的仓库设置成了远程仓库,并向 这个仓库 push 了 feature-D 分支。现在,所有能够访问这个远程仓库的 人都可以获取 feature-D 分支并加以修改。 本节中我们从实际开发者的角度出发,在另一个目录下新建一个本 地仓库,学习从远程仓库获取内容的相关操作。这就相当于我们刚刚执 行过 push 操作的目标仓库又有了另一名新开发者来共同开发。

git clone——获取远程仓库

获取远程仓库

首先我们换到其他目录下,将 GitHub 上的仓库 clone 到本地。注意不要与之前操作的仓库在同一目录下。

$ git clone git@github.com:github-book/git-tutorial.git Cloning into 'git-tutorial'...
remote: Counting objects: 20, done.
remote: Compressing objects: 100% (7/7), done. 
remote: Total 20 (delta 3), reused 20 (delta 3) Receiving objects: 100% (20/20), done. Resolving deltas: 100% (3/3), done.
$ cd git-tutorial

::执行git clone命令后::我们会::默认处于master分支下::,同时::系统会自动将 origin 设置成该远程仓库的标识符::。也就是说,当前::本地仓库 的 master 分支与 GitHub 端远程仓库(origin)的 master 分支在内容上是 完全相同的::。

$ git branch -a 
* master 
remotes/origin/HEAD -> origin/master 
remotes/origin/feature-D 
remotes/origin/master

我们用git branch -a命令查看当前分支的相关信息。添加-a 参数可以::同时显示本地仓库和远程仓库的分支信息::。 结果中显示了remotes/origin/feature-D,证明我们的 ~远程仓库中已经 有了 feature-D~ 分支。

获取远程的 feature-D 分支

我们试着将 feature-D 分支获取至本地仓库。

$ git checkout -b feature-D origin/feature-D
Branch feature-D set up to track remote branch feature-D from origin. 
Switched to a new branch 'feature-D'

::-b 参数的后面是本地仓库中新建分支的名称::。 为了便于理解,我们::仍将其命名为 feature-D::,让::它与远程仓库的对应分支保持同名::。 ::新建分支名称::后面是::获取来源的分支名称::。 例子中指定了 ::origin/feature-D::, 就是说::以名为 origin 的仓库::(这里指 GitHub 端的仓库)的 ::feature-D 分 支::为来源,::在本地仓库中创建 feature-D 分支::。

向本地的 feature-D 分支提交更改

现在假定我们是另一名开发者,要做一个新的提交。在 README. md 文件中添加一行文字,查看更改。

$ git diff
diff --git a/README.md b/README.md index af647fd..30378c9 100644
--- a/README.md
+++ b/README.md
@@ -3,3 +3,4 @@ 
- feature-A - fix-B
- feature-C 
+ - feature-D

按照之前学过的方式提交即可。

$ git commit -am "Add feature-D" 
[feature-D ed9721e] Add feature-D 
1 file changed, 1 insertion(+)

推送 feature-D 分支

$ git push
Counting objects: 5, done.
Delta compression using up to 8 threads. Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 281 bytes, done. 
Total 3 (delta 1), reused 0 (delta 0)
To git@github.com:github-book/git-tutorial.git 
ca0f98b..ed9721e feature-D -> feature-D

从远程仓库获取 feature-D 分支,在本地仓库中提交更改,再将 feature-D 分支推送回远程仓库,通过这一系列操作,就可以与其他开发 者相互合作,共同培育 feature-D 分支,实现某些功能。

git pull——获取最新的远程仓库分支

现在我们放下刚刚操作的目录,回到原先的那个目录下。这边的本地仓库中只创建了 feature-D 分支,并没有在 feature-D 分支中进行任何提交。然而远程仓库的 feature-D 分支中已经有了我们刚刚推送的提交。 这时我们就可以使用 git pull 命令,将本地的 feature-D 分支更新到最新状态。当前分支为 feature-D 分支。

$ git pull origin feature-D
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (1/1), done. remote: Total 3 (delta 1), reused 3 (delta 1) Unpacking objects: 100% (3/3), done.
From github.com:github-book/git-tutorial 
* branch feature-D -> FETCH_HEAD
First, rewinding head to replay your work on top of it... Fast-forwarded feature-D to ed9721e686f8c588e55ec6b8071b669f411486b8.

GitHub 端远程仓库中的 feature-D 分支是最新状态,所以本地仓库 中的 feature-D 分支就得到了更新。::今后只需要像平常一样在本地进行提 交再 push 给远程仓库,就可以与其他开发者同时在同一个分支中进行作业,不断给 feature-D 增加新功能::。 ::如果两人同时修改了同一部分的源代码,push 时就很容易发生冲 突。所以多名开发者在同一个分支中进行作业时,为减少冲突情况的发 生,建议更频繁地进行 push 和 pull 操作::。

更多关于git的知识如何学习

掌握以上知识就可以应付大部分开发工作了,其余知识可通过下列途径学习或google。

Pro Git

http://git-scm.com/book/zh/v1 Pro Git 由就职于 GitHub 公司的 Scott ChaconB 执笔,是一部零基础的 Git 学习资料。基于知识共享的 CC BY-NC-SA 3.0 许可协议,各位可以免费阅读到包括简体中文在内的各国语言版本。

LearnGitBranching

http://pcottle.github.io/learnGitBranching/ LearnGitBranching 是学习 Git 基本操作的网站(图 4.9)。注重树形结构的学习方式非常适合初学者使用,点击右下角的地球标志还可切换各种语言进行学习。

tryGit

http://try.github.io/ 通过 tryGitB 我们可以在 Web 上一边操作一边学习 Git 的基本功能 (图 4.10)。很可惜该教程只有英文版。