github入门与实战-读书笔记
Gitub
克隆github仓库:执行 git clone命令后我们会默认处于 master 分支下,同时系统会自动将 origin 设置成该远程仓库的标识符。
将本地仓库推送至github:在github中新建一个仓库。创建时请不要勾选 Initialize this repository with a README 选项(如果勾选,则远程将建立一个分支,与本地仓库冲突)。
git push -u origin master
:-u参数可以在推送的同时,将 origin 仓库的 master 分支设置为本地仓库当前分支的 upstream(上游)。添加了这个参数,将来运行 git pull命令从远程仓库获取内容时,本地仓库的这个分支就可以直接从 origin 的 master 分支获取内容,省去了另外添加参数的麻烦。
git checkout -b feature-D origin/feature-D:获取远程的 feature-D 分支。此命令会将远程设为上游,直接 git push
即可。
git pull——获取最新的远程仓库分支
团队合作 Pull Request
Pull Request 是自己修改源代 码后,请求对方仓库采纳该修改时采取的一种行为。
虽然可以代码完成后再发送 Pull Request,但在实际开发过程中,这样做很可能导致一个功能在完成后才收到设计或实现方面的指正,从而使代码需要大幅更改或重新实现。 在 GitHub 上,我们可以尽早创建 Pull Request,从审查中获得反馈, 让大家在设计与实现方面思路一致,借此逐渐提高代码质量。这个方法在团队开发大型项目时尤其有效,已将 GitHub 运用到实际开发中的团队请务必试一试。
即便某个功能尚在开发之中,只要在 Pull Request 中附带一段简单代码让大家有个大体印象,就能获取不少反馈。 如果在 Pull Request 中再加入直观易懂的 Tasklist,就能很清楚反映出哪些功能已经实现,将来要做哪些工作。这不但能加快审查者的工作效率,还能作为自己的备忘录使用。
向发送过 Pull Request 的分支添加提交时,该提交会自动添加至已发送的 Pull Request 中。 这一方法要求尽早发送 Pull Request,越早效果越明显。另外还有一件事要记住,就是千万不要在 Pull Request 中添加无关的修改。处理与主题无关的作业请另外创建分支,不然会让原本清晰的讨论变得一团糟。
前期准备
- fork创建自己的仓库
- 克隆到本地。’git clone git@…..’。
- 创建新分支,在新分支中作业。发送pull request时,一般都是发送特性分支,这样,pull request就有了更明确的特性(主题)。让对方了解自己修改代码的意图,有助于提高代码审查效率。
- 创建远程分支。
Fork 工作流
当前 Git 的主流开发模式都会使用特性分支。各位请养成创建特性分支后再修改代码的好习惯。在 GitHub 上发送 Pull Request 时,一般都是发送特性分支。这样一来,Pull Request 就拥有了更明确的特性(主题)。让对方了解自己修改代码的意图,有助于提高代码审查的效率。
在无法给不特定的多数人赋予提交权限的公开软件开发中,Fork流程能够防止仓库收到计划之外的提交。 然而在公司企业的开发中,开发者每天都要见面,要经常互相发送 Pull Request,这种流程就显得有些繁琐了。
GitHub Flow——以部署为中心的开发模式
由 20 人左右的团队使用这个流程来共同开发一个项目,基本不会出现什么大问题。
整个开发流程大致如下。
- 令 master 分支时常保持可以部署的状态
- 进行新的作业时要从 master 分支创建新分支,新分支名称要具有描述性
- 在第二步新建的本地仓库分支中进行提交
- 在 GitHub 端仓库创建同名分支,定期 push
- 需要帮助或反馈时创建 Pull Request,以 Pull Request 进行交流
- 让其他开发者进行审查,确认作业完成后与 master 分支合并
- 与 master 分支合并后立刻部署
要点:
- master分支时常保持可以部署的状态,保证代码无Bug
- 创建新分支前先pull,在最新代码上修改
- 新分支名要具有描述性,其他开发者可以清除了解该分支正在进行什么工作。
- 一个功能分成几个小 pull request:防止过大代码量难以阅读
- 一个pull request多次commit:让每个差别有更清晰的定义
- 修改代码时要注意不要进行与该分支内容无关的修改
- 定期push,让其他人能够看到自己的代码,创建交流的机会。以尽早创建 Pull Request 让其他开发者进行审查,一边 听取反馈一边编写代码,没必要等到与 master 分支合并时再进行。
Git Flow——以发布为中心的开发模式
- 从开发版的分支(develop)创建工作分支(feature branches),进 行功能的实现或修正
- 工作分支(feature branches)的修改结束后,与开发版的分支 (develop)进行合并
- 重复上述❶和❷,不断实现功能直至可以发布
- 创建用于发布的分支(release branches),处理发布的各项工作
- 发布工作完成后与 master 分支合并,打上版本标签(Tag)进行发布
- 如果发布的软件出现 BUG,以打了标签的版本为基础进行修正 (hotfixes)
推荐工具git-flow来辅助开发。
由于在实际开发现场需要多人分工合作,这一开发流程往往会变得很复杂。建议各位把开发流程图放大并张贴在墙壁上,这样能够有效帮助团队成员理解流程内容。
GIT
初始设置
- 设置使用 Git 时的姓名和邮箱地址。
1 | 名字请用英文输入。命令会应用到“~/.gitconfig”中,也可以直接编辑这个文件。 |
这里设置的姓名和邮箱地址会用在 Git 的提交日志中。由于在 GitHub 上公开仓库时,这里的姓名和邮箱地址也会随着提交日志一同被公开,所以请不要使用不便公开的隐私信息。
设置SSH Key
$ ssh-keygen -t rsa -C "your_email@example.com"
id_rsa 文件是私有密钥,id_rsa.pub 是公开密钥。
在 GitHub 中添加公开密钥,今后就可以用私有密钥进行认证了。
设置后,通过命令 ssh -T git@github.com
来测试与github的连接
文件管理
1 | git clone git@github.com:......gitz |
git init
:在当前文件夹下创建仓库,会生成.git文件,其中记录了该仓库有关数据git status
:查看仓库状态,包括未跟踪的文件,修改但未提交的文件。
git add filename
——将文件加入暂存区
git add -A
:添加当前目录中的所有文件git add .
:添加当前目录中所有文件更改git add -p
:选择要添加的更改(可以Y或N完成所有的更改)
git commit -m "comment"
—-提交。如果没有参数-m,就会启动编辑器。将提交信息留空并直接关闭编辑器,会中止提止。:
在编辑器中记录提交信息的格式为
第一行:用一行文字简述提交的更改内容
第二行:空行
第三行以后:记述更改的原因和详细内容。
git commit -am
等于执行 git add命令 再执行 git commit命令
git log
:查看谁在什么时候进行了提交或合并,以及操作前后的差别。如果嫌输出信息太多,可以试试加上 --pretty=oneline
参数,git log --pretty=short
git diff
:查看工作树和暂存区的差别。
git diff HEAD
:查看工作树和最新提交的差别。好习惯:在执行 git commit命令之前先执行 git diff HEAD命令,查看本次提交与上次提交之间有什么差别,等 确认完毕后再进行提交。这里的 HEAD 是指向当前分支中最新一次提交 的指针。
忽略文件:
如果将其他的git仓库添加到暂存区中,会出现:
1 | hint: You've added another git repository inside your current repository. |
可将该git仓库路径添加到.gitignore文件中。一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以创建一个名为 .gitignore的文件,列出要忽略的文件的模式。
1 | $ cat .gitignore |
第一行告诉 Git 忽略所有以 .o 或 .a 结尾的文件。一般这类对象文件和存档文件都是编译过程中出现的。 第二行告诉 Git 忽略所有名字以波浪符(~)结尾的文件,许多文本编辑软件(比如 Emacs)都用这样的文件名保存
副本。 此外,你可能还需要忽略 log,tmp 或者 pid 目录,以及自动生成的文档等等。 要养成一开始就为你的新仓库设置好 .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 等。
1 | # 忽略所有的 .a 文件 |
GitHub 有一个十分详细的针对数十种项目及语言的 .gitignore 文件列表, 你可以在https://github.com/github/gitignore 找到它。
在最简单的情况下,一个仓库可能只根目录下有一个 .gitignore 文件,它递归地应用到整个仓库中。 然而,子目录下也可以有额外的 .gitignore 文件。子目录中的 .gitignore文件中的规则只作用于它所在的目录中。 (Linux 内核的源码库拥有 206 个 .gitignore 文
件。)
多个 .gitignore 文件的具体细节超出了本书的范围,更多详情见 man gitignore 。
分支管理
查看分支:git branch
。显示的结果中, *
号标记的是前所在的位置。 -a 参数可以同时显示本地和远程仓库的信息。可用 git log --graph
以图表形式查看分支。
创建分支:git branch A
。会在当前所提交的对象上创建一个新指针,这样,当前对象有两个指针(比如master和A)指向它,git通过特殊指针Head来辨别目前在哪一个分支上(可以将Head想象为当前所在分支的别名)。
切换分支:git checkout A
或者 git switch A
。
切换至上一个分支:git checkout -
在切换分支之前,留意工作目录和暂存区中还未被提交的修改,它可能会和即将迁出的分支产生冲突从而阻止git切换到该分支。最好的方法是在迁出前保持一个干净的状态。见”贮藏与清理“一节。现在,我们假设你已经把你的修改全部提交了。
创建+切换分支:git checkout -b A
或者 git switch -c <name>
删除分支:git branch -d <name>
合并分支A到当前分支:git merge A
。–no-ff参数启动编辑器,用于录入合并提交的信息。
在A上所做的工作并没有包含在其他分支如B中。如果B想要拉取A所作的修改,可以使用git merge master来和master分支合并,或者也可以等到B分支完成后,再将其合并到master分支。
Rebase
rebase操作可以把本地未push的分叉提交历史整理成直线; 现在假设我们在本地上提交了两次。用`(HEAD -> master)`和`(origin/master)`标识出当前分支的HEAD和远程origin的位置分别是`582d922 add author`和`d1be385 init hello`1 | $ git log --graph --pretty=oneline --abbrev-commit |
然后我们尝试推送本地分支,如果失败,说明有人先于我们推送了远程分支。按照经验,先pull一下(pull会自动merge),最后结果是提交历史分叉了。
1 | $ git log --graph --pretty=oneline --abbrev-commit |
Rebase命令可以让提交历史变成一条干净的直线(https://www.liaoxuefeng.com/wiki/896043488029600/1216289527823648 )。Git的文档特别强调需要注意的使用情形和原则: 只对尚未推送或分享给别人的本地修改执行变基操作清理历史,从不对已推送至别处的提交执行变基操作。 因为rebase会改变提交历史记录,这会影响到别人使用这一远程仓库。
版本回退
- 查看提交历史,用
git log
命令看历史。回退,用git reset --hard HEAD^
命令:用HEAD
表示当前版本,上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,当然往上100个版本写100个^
比较容易数不过来,所以写成HEAD~100
。 git log
命令只能查看以当前状态为终点的历史日志。使用git reflog
命令可查看当前仓库的操作日志。在日志中找出 回溯历史之前的哈希值,通过 git reset –hard命令恢复到回溯历 史前的状态。历史之间穿梭:git reset –-hard (commit id)
。版本号没必要写全,前几位就可以了,Git会自动去找。
穿梭前,用 git log
可以查看提交历史,要重返未来,用 git reflog
查看命令历史
git rebase -i HEAD~2——将这个修改包含到前一个提交之中,压缩成一 个历史记录。
撤销修改
git commit -amend: 重新提交,将替换上一次的提交。不会让“啊,忘了添加一个文件”或者“小补修,修正笔误”这样的提交信息弄乱你的仓库历史。
取消暂存的文件和撤销对文件的修改
使用git status 命令来查看当前的状态,它提示了可用命令
1 | $ git status |
针对“Changes to be committed”,可以使用”git restore –staged <file>
…” 来取消暂存:
1 | $ git restore --staged * |
命令 “git restore <file>
…” 会将文件还原成最近提交时的样子 ,丢弃工作区所有修改。该命令不会删除还未tracked的新建文件。
git clean : Remove untracked files from the working tree。
usage : git clean [-d] [-f] [-i] [-n] [-q] [-e
<pattern>
] [-x | -X] [–]<paths>
.
如果你仍然想保留对那个文件做出的修改,但是现在仍然需要撤消,我们将会在 Git 分支 介绍保存进度与分支,这通常是更好的做法。
记住,在 Git 中任何 已提交 的东西几乎总是可以恢复的。 甚至那些被删除的分支中的提交或使用 –amend 选项覆盖的提交也可以恢复 (阅读 数据恢复 了解数据恢复)。 然而,任何你未提交的东西丢失后很可能再也找不到了。
git: undo all working dir changes including new files | stackoverflow