一篇极好的Git 总结

12次阅读

共计 6859 个字符,预计需要花费 18 分钟才能阅读完成。

欢迎大家前往腾讯云 + 社区,获取更多腾讯海量技术实践干货哦~
本文由腾讯工蜂发表于云 + 社区专栏

常用命令
简单的,常用的命令也就几个。但是想非常熟练使用,怕是要记住几十个。

Workspace:工作区(clone 或者原始内容)
Index/Stage:暂存区(有增删改查后 add 到临时区)
Repository:本地仓库(保存了本地的增删改查记录)
Remote:远程仓库(git.code.oa.com,本地的记录提交到远端,供团队所有人查看使用)

有意思的事
代码更新之 Fetch vs Pull
二者都是从远程拉取代码到本地

fetch:只是拉取到本地
pull:不仅拉取到本地,还 merge 到本地分支中

代码合流之 Merge vs Rebase
rebase:用于把一个分支的修改合并到当前分支

假设远程分支上有 2 个提交,然后基于远程 develop,再创建一个分支 feature。
然后分别在两个分支上做两次提交。

git merge
这时候,你可以用 pull 命令把 develop 分支上的修改拉下来并且和你的修改合并;结果看起来就像一个新的和并提交

git rebase
$ git checkout feature
$ git rebase develop

这些命令会把你的 feature 分支里的每个提交 (commit) 取消掉,并且把它们临时保存为补丁(patch)(这些补丁放到 ”.git/rebase” 目录中)
然后把 feature 分支更新为最新的 develop 分支
最后把保存的这些补丁应用到 feature 分支上
当 feature 分支更新后,会指向最新的 commit,临时存放的就会被删除掉

代码回滚之 Reset、Revert、Checkout

Reset
将一个分支的末端指向另一个提交,可以用来移除当前分支的一些提交。
文件层面上,将缓存区的文件同步到指定的那个提交。
$ git checkout develop
$ git reset HEAD~2

# 将当前的 README.md 从缓存区中移除出去
$ git reset HEAD README.md

develop 分支末端的两个提交就变成了悬挂提交
如果提交还没有 push,git reset 是撤销 commit 的简单方法
除了在当前分支上操作,还可以通过其他参数来修改 stage 或者 workspace

–soft:stage 和 workspace 都不会被改变
–mixed(默认):stage 和你指定的提交同步,但 workspace 不受影响
–hard:stage 和 workspace 都同步到你指定的提交

# 将当前的改动从 stage 中移除,但这些改动还保留在 workspace 中
$ git reset –mixed HEAD

# 完全舍弃没有提交的改动
$ git reset –hard HEAD
Checkout
提交层面上的 checkout,可以切换分支,同一分支,可以切换当前 HEAD。
文件层面上,不会移动 HEAD 指针,也不会切换到其他分支上,只是更改 workspace,而不是 stage。
# 将 HEAD 移到新的分支,然后更新工作目录
$ git checkout develop

# 将 HEAD 移动到当前 commit 的前两个 commit 上,同时更新 workspace
$ git checkout HEAD~2

# 将 workspace 中的 README.md 同步到最新的提交
$ git checkout HEAD README.md
Revert
撤销一个提交的同时会创建一个新的提交。
# 产生一个新的 commit 用于撤销倒数第二个 commit
$ git checkout develop
$ git revert HEAD~2

不会改变提交历史
revert 可以用在公共分支,reset 应该用在私有分支上
如果提交已经 push,想到达到撤销的目的,应该使用 revert

命令
作用域
常用情景

git reset
提交层面
在私有分支上舍弃一些没有提交的更改

git reset
文件层面
将文件从缓存区中移除

git checkout
提交层面
切换分支或查看旧版本

git checkout
文件层面
舍弃工作目录中的更改

git revert
提交层面
在公共分支上回滚更改

git revert
文件层面
(然而并没有)

代码暂存之 Stash
git stash 会把所有未提交的修改(包括暂存和未暂存的)都保存起来,用于日后恢复当前工作目录

保存一个不必要但日后又想查看的提交
切换分支前先暂存,处理分支的其他事情

$ git status
On branch develop
Changes to be committed:

new file: README.md

Changes not staged for commit:

modified: index.html

$ git stash
Saved working directory and index state WIP on master: 5002d47 …

$ git status
On branch master
nothing to commit, working tree clean
stage 是本地的,不会上传到 git server
实际应用中,推荐给每个 stash 加一个 message,使用 git stash save 取代 git stash
$ git stash save “test stash”
Saved working directory and index state On autoswitch: test stash
HEAD 现在位于 296e8d4 remove unnecessary postion reset in onResume function
$ git stash list
stash@{0}: On autoswitch: test stash
可以使用 git stash list 命令,查看 stash 列表
$ git stash list
stash@{0}: WIP on master: 049d078 stash_0
stash@{1}: WIP on master: c264051 stash_1
stash@{2}: WIP on master: 21d80a5 stash_2
2. 使用 git stash apply 命令可以通过名字指定那个 stash,默认指定最近的(stash@{0})
3. 使用 git stash pop 将 stash 中第一个 stash 删除,并将对应修改应用到当前的工作目录中
4. 使用 git stash drop,后面加上 stash 名,可以移除相应的 stash;或者使用 git stash clear 清空所有 stash
默认情况下,git stash 会缓存:

添加到暂存区的修改(staged changes)
Git 跟踪但并未添加到暂存区的修改(unstaged changes)

但不会缓存:

在工作目录中新的文件(untracked files)
被忽略的文件(ignored files)

此时,使用 - u 或者 –include-untracked 可以 stash untracked 文件;使用 - a 或者 –all 可以 stash 当前目录下的所有修改(慎用)
基础命令
初始化
# 在当前目录新建一个 Git 代码库
$ git init

# 新建一个目录,将其初始化为 Git 代码库
$ git init git_test

# 下载一个项目和它的整个代码历史
$ git clone http://git.code.oa.com/jaelintu/git_test
增加 / 删除文件
# 添加指定文件到暂存区
$ git add file1 file2…

# 添加指定目录到暂存区,包括子目录
$ git add dir

# 添加当前目录的所有文件到暂存区
$ git add .

# 添加每个变化前,都会要求确认
# 对于同一个文件的多处变化,可以实现分次提交
$ git add -p

# 删除工作区文件,并且将这次删除放入暂存区
$ git rm file1 file2 …
代码提交
# 提交暂存区到仓库区
$ git commit -m “message”

# 提交暂存区的指定文件到仓库区
$ git commit file1 file2 … -m “message”

# 提交工作区自上次 commit 之后的变化,直接到仓库区
$ git commit -a

# 提交时显示所有 diff 信息
$ git commit -v

# 使用一次新的 commit,替代上一次提交
# 如果代码没有任何新变化,则用来改写上一次 commit 的提交信息
$ git commit –amend -m “message”

# 重做上一次 commit,并包括指定文件的新变化
$ git commit –amend file1 file2 …
分支
# 列出所有本地分支
$ git branch

# 列出所有远程分支
$ git branch -r

# 列出所有本地分支和远程分支
$ git branch -a

# 新建一个分支,但依然停留在当前分支
$ git branch name

# 新建一个分支,并切换到该分支
$ git checkout -b branch

# 新建一个分支,指向指定 commit
$ git branch name commit_SHA

# 新建一个分支,与指定的远程分支建立追踪关系
$ git branch –track name orgin/name

# 切换到指定分支,并更新工作区
$ git checkout name

# 切换到上一个分支
$ git checkout –

# 建立追踪关系,在现有分支与指定的远程分支之间
$ git branch –set-upstream name origin/name

# 合并指定分支到当前分支
$ git merge branch-name

# 选择一个 commit,合并进当前分支
$ git cherry-pick commit_SHA

# 删除分支
$ git branch -d branch-name

# 删除远程分支
$ git push origin –delete branch-name
$ git branch -dr remote/branch
tags
# 列出所有 tag
$ git tag

# 新建一个 tag 在当前 commit
$ git tag tag-name

# 新建一个 tag 在指定 commit
$ git tag tag-name commit-SHA

# 删除本地 tag
$ git tag -d tag-name

# 删除远程 tag
$ git push origin :refs/tags/tag-Name

# 查看 tag 信息
$ git show tag-name

# 提交指定 tag
$ git push origin tag-name

# 提交所有 tag
$ git push origin –tags

# 新建一个分支,指向某个 tag
$ git checkout -b branch-name tag-name
查看信息
# 显示有变更的文件
$ git status

# 显示当前分支的版本历史
$ git log

# 显示 commit 历史,以及每次 commit 发生变更的文件
$ git log –stat

# 搜索提交历史,根据关键词
$ git log -S [keyword]

# 显示某个 commit 之后的所有变动
$ git log (tag-name||commit-SHA) HEAD

# 显示某个文件的版本历史,包括文件改名
$ git log –follow file
$ git whatchanged file

# 显示指定文件相关的每一次 diff
$ git log -p file

# 显示过去 5 次提交
$ git log -5 –pretty –oneline

# 显示所有提交过的用户,按提交次数排序
$ git shortlog -sn

# 显示指定文件是什么人在什么时间修改过
$ git blame file

# 显示暂存区和工作区的代码差异
$ git diff

# 显示暂存区和上一个 commit 的差异
$ git diff –cached file

# 显示工作区与当前分支最新 commit 之间的差异
$ git diff HEAD

# 显示两次提交之间的差异
$ git diff [first-branch]…[second-branch]

# 显示今天你写了多少行代码
$ git diff –shortstat “@{0 day ago}”

# 显示某次提交的元数据和内容变化
$ git show commit-SHA

# 显示某次提交发生变化的文件
$ git show –name-only commit-SHA

# 显示某次提交时,某个文件的内容
$ git show commit-SHA:filename

# 显示当前分支的最近几次提交
$ git reflog

# 从本地 master 拉取代码更新当前分支:branch 一般为 master
$ git rebase branch-name
远程同步
# 下载远程仓库的所有变动
$ git fetch origin

# 显示所有远程仓库
$ git remote -v

# 显示某个远程仓库的信息
$ git remote show origin

# 增加一个新的远程仓库,并命名
$ git remote add shortname url

# 取回远程仓库的变化,并与本地分支合并
$ git pull origin branch-name

# 上传本地指定分支到远程仓库
$ git push origin branch-name

# 强行推送当前分支到远程仓库,即使有冲突
$ git push origin –force

# 推送所有分支到远程仓库
$ git push origin –all
撤销
# 恢复暂存区的指定文件到工作区
$ git checkout file

# 恢复某个 commit 的指定文件到暂存区和工作区
$ git checkout commit-SHA file

# 恢复暂存区的所有文件到工作区
$ git checkout .

# 重置暂存区的指定文件,与上一次 commit 保持一致,但工作区不变
$ git reset file

# 重置暂存区与工作区,与上一次 commit 保持一致
$ git reset –hard

# 重置当前分支的指针为指定 commit,同时重置暂存区,但工作区不变
$ git reset commit-SHA

# 重置当前分支的 HEAD 为指定 commit,同时重置暂存区和工作区,与指定 commit 一致
$ git reset –hard commit-SHA

# 重置当前 HEAD 为指定 commit,但保持暂存区和工作区不变
$ git reset –keep commit-SHA

# 新建一个 commit,用来撤销指定 commit
# 后者的所有变化都将被前者抵消,并且应用到当前分支
$ git revert commit-SHA

# 暂时将未提交的变化移除,稍后再移入
$ git stash
$ git stash pop
冲突解决
rebase 过程中,也许会出现冲突(conflict)

git 会停止 rebase,需要解决冲突
解决完,使用 git add 添加冲突的文件,更新暂存区

git rebase –continue 继续剩下的 rebase

git rebase –abort 终止 rebase 行为,并且 feature 会回到 rebase 开始之前的状态

$ git rebase develop
CONFLICT (content): Rebase conflict in readme.txt
Automatic rebase failed; fix conflicts and then commit the result.

$ git status
On branch feature

You have unmerged paths.
(fix conflicts and run “git rebase –continue”)
(use “git merge –abort” to abort the merge)

Unmerged paths:
(use “git add <file>…” to mark resolution)

both modified: readme.txt

no changes added to commit (use “git add” and/or “git commit -a”)
查看 readme.md 内容
Git tracks changes of files.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature
选择保留 HEAD 或者 feature 的版本
Git tracks changes of files.
Creating a new branch is quick AND simple.
在提交:
$ git add readme.md
$ git rebase –contine
推荐的 Git GUI 工具
1. Source Tree(号称最好用):特色支持 git flow,一键创建工作流

免费功能
强大:无论你是新手还是重度用户,SourceTree 都会让你觉得很顺手。对于非常重度用户,Source Tree 还支持自定义脚本的执行
同时支持 Windows 和 Mac 操作系统
同时支持 Git 和 Mercurial 两种 VCS
内置 GitHub, BitBucket 和 Stash 的支持:直接绑定帐号即可操作远程 repo2. Tortoise git:文件的右键菜单很容易上手

免费
只支持 Windows:与文件管理器良好集成
中文界面
与 Tortoise SVN 相同的体验

相关阅读【每日课程推荐】机器学习实战!快速入门在线广告业务及 CTR 相应知识

此文已由作者授权腾讯云 + 社区发布,更多原文请点击
搜索关注公众号「云加社区」,第一时间获取技术干货,关注后回复 1024 送你一份技术课程大礼包!

正文完
 0