首先要搞清楚下面几个概念
HEAD:HEAD就是指向当前分支当前版本的游标- Index/stage: Index即为暂存区,当你修改了你的git仓库里的一个文件时,这些变化一开始是unstaged状态,为了提交这些修改,你需要使用
git add把它加入到index,使它成为staged状态。当你提交一个commit时,index里面的修改被提交。 - working tree: 即当前的工作目录。
工作区域转换
from index to working directory: git restore --staged xx or git reset commit/HEAD.
from head to index: git reset commit --soft 把去除的commit的changes恢复到stage了
modifed files from index to working directory: git co
最基本的提交代码
Git add .
Git commit -m "xx"
Git push origin
分支创建
建立自己分支
Git branch newName
Git checkout newName 切换分支
可以直接git checkout -b newName创建并切换
查看当前分支 git branch
建立本地测试分支连到自己的远程分支使用
git checkout -b dev_mfl_test origin/dev_mafulong
分支删除
删除分支:git branch -d <name>
查看远程分支:
git branch -a
使用命令,git branch -d Chapater8 可以删除本地分支(在主分支中)
使用命令 git push origin --delete Chapater6 可以删除远程分支Chapater6
分支更新
gl = git pull
远程最新的更新旧的本地
git pull origin
要取回origin主机的next分支,与本地的master分支合并,需要写成下面这样 -
git pull origin next:master
在本地创建新的分支提交远程时,需要
git push --set-upstream origin dev_mafulong1
以后就可以 push 自己这个分支了
Git push origin 分支名
git push origin item_pack_mfl
当我想从远程仓库里拉取一条本地不存在的分支时:
git checkout -b 本地分支名 origin/远程分支名
这个将会自动创建一个新的本地分支,并与指定的远程分支关联起来。
git show 显示修改了啥
git show
一、新建代码库
在当前目录新建一个 Git 代码库 $ git init
新建一个目录,将其初始化为 Git 代码库 $ git init [project-name]
下载一个项目和它的整个代码历史 $ git clone [url]
二、配置
Git 的设置文件为.gitconfig,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。
显示当前的 Git 配置 $ git config –list
编辑 Git 配置文 $ git config -e [–global]
设置提交代码时的用户信息 $ git config [–global] user.name “[name]” $ git config [–global] user.email “[email address]”
三、增加/删除文件
添加指定文件到暂存区 $ git add [file1] [file2] …
添加指定目录到暂存区,包括子目录 $ git add [dir]
添加当前目录的所有文件到暂存区 $ git add .
添加每个变化前,都会要求确认 对于同一个文件的多处变化,可以实现分次提交 $ git add -p
删除工作区文件,并且将这次删除放入暂存区 $ git rm [file1] [file2] …
停止追踪指定文件,但该文件会保留在工作区 $ git rm –cached [file]
改名文件,并且将这个改名放入暂存区 $ git mv [file-original] [file-renamed]
四、代码提交
提交暂存区到仓库区 $ 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 [branch-name]
新建一个分支,并切换到该分支 $ git checkout -b [branch]
新建一个分支,指向指定 commit $ git branch [branch] [commit]
新建一个分支,与指定的远程分支建立追踪关系 $ git branch –track [branch] [remote-branch]
切换到指定分支,并更新工作区 $ git checkout [branch-name]
切换到上一个分支 $ git checkout -
建立追踪关系,在现有分支与指定的远程分支之间 $ git branch –set-upstream [branch] [remote-branch]
合并指定分支到当前分支 $ git merge [branch]
选择一个 commit,合并进当前分支 $ git cherry-pick [commit]
删除分支 $ git branch -d [branch-name]
删除远程分支 $ git push origin –delete [branch-name] $ git branch -dr [remote/branch]
六、标签
列出所有 tag $ git tag
新建一个 tag 在当前 commit $ git tag [tag]
新建一个 tag 在指定 commit $ git tag [tag] [commit]
删除本地 tag $ git tag -d [tag]
删除远程 tag $ git push origin :refs/tags/[tagName]
查看 tag 信息 $ git show [tag]
提交指定 tag $ git push [remote] [tag]
提交所有 tag $ git push [remote] –tags
新建一个分支,指向某个 tag $ git checkout -b [branch] [tag]
七、查看信息
显示有变更的文件 $ git status
显示当前分支的版本历史 $ git log
显示 commit 历史,以及每次 commit 发生变更的文件 $ git log –stat
搜索提交历史,根据关键词 $ git log -S [keyword]
显示某个 commit 之后的所有变动,每个 commit 占据一行 $ git log [tag] HEAD –pretty=format:%s
显示某个 commit 之后的所有变动,其”提交说明”必须符合搜索条件 $ git log [tag] HEAD –grep feature
显示某个文件的版本历史,包括文件改名 $ 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]
显示某次提交发生变化的文件 $ git show –name-only [commit]
显示某次提交时,某个文件的内容 $ git show [commit]:[filename]
显示当前分支的最近几次提交 $ git reflog 八、远程同步 下载远程仓库的所有变动 $ git fetch [remote]
显示所有远程仓库 $ git remote -v
显示某个远程仓库的信息 $ git remote show [remote]
增加一个新的远程仓库,并命名 $ git remote add [shortname] [url]
取回远程仓库的变化,并与本地分支合并 $ git pull [remote] [branch]
上传本地指定分支到远程仓库 $ git push [remote] [branch]
强行推送当前分支到远程仓库,即使有冲突 $ git push [remote] –force
推送所有分支到远程仓库 $ git push [remote] –all 九、撤销 恢复暂存区的指定文件到工作区 $ git checkout [file]
恢复某个 commit 的指定文件到暂存区和工作区 $ git checkout [commit] [file]
恢复暂存区的所有文件到工作区 $ git checkout .
重置暂存区的指定文件,与上一次 commit 保持一致,但工作区不变 $ git reset [file]
重置暂存区与工作区,与上一次 commit 保持一致 $ git reset –hard
重置当前分支的指针为指定 commit,同时重置暂存区,但工作区不变 $ git reset [commit]
重置当前分支的 HEAD 为指定 commit,同时重置暂存区和工作区,与指定 commit 一致 $ git reset –hard [commit]
重置当前 HEAD 为指定 commit,但保持暂存区和工作区不变 $ git reset –keep [commit]
新建一个 commit,用来撤销指定 commit 后者的所有变化都将被前者抵消,并且应用到当前分支 $ git revert [commit]
暂时将未提交的变化移除,稍后再移入 $ git stash $ git stash pop
commit rebase多合一
git rebase -i head~2 //合并最近的2个commit
//之后把pick改成d
//终止
git rebase --abort
G H I J
\ / \ /
D E F
\ | / \
\ | / |
\|/ |
B C
\ /
\ /
A
A = = A^0
B = A^ = A^1 = A~1
C = A^2 = A^2
D = A^^ = A^1^1 = A~2
E = B^2 = A^^2
F = B^3 = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2 = B^^2 = A^^^2 = A~2^2
I = F^ = B^3^ = A^^3^
J = F^2 = B^3^2 = A^^3^2
G-D-B-A 可以认为是主干,其他都是 merge 进来的其他分支节点。
A^表示 A 的第一个父提交,A^2 表示 A 的第二个父提交
A~1 表示 A 的父提交,A~2 表示 A 的父提交的父提交,相当于 A^^和 A^1^1
A~2^2 表示 A 的父提交的父提交的第二个父提交,即为 H
“^”代表父提交,当一个提交有多个父提交时,可以通过在”^”后面跟上一个数字,表示第几个父提交,”^”相当于”^1”.
~n相当于连续的n个”^”.
git checkout 恢复文件
git co .
只能恢复非stage的文件。
git reset
Reset一词是指撤销修改。git reset 命令被用来重置更改。git reset 命令有三种核心调用形式。这些形式如下。
- Soft
- Mixed
- Hard

git reset [--soft | --mixed | --hard] [HEAD]
–mixed 为默认,可以不用带该参数,用于重置暂存区的文件与上一次的提交(commit)保持一致,工作区文件内容保持不变。
--mixed reset HEAD and index 被抹去的commit的changes以及work directory的changes都会保留到work directory. 不会丢,只不过commit信息没了,修改都在。
--soft reset only HEAD 被抹去的commit的changes会保留到stage, unstage的还是unstage,不会丢,commit信息没了
--hard reset HEAD, index and working tree 被抹去的commit的changes没了,unstage的还在,还是unstage.
git help reset
soft
- unstage -> unstage 不影响
- Staged -> staged 不影响
- commited -> staged
mixed
- staged -> unstage
- commited -> unstage
- unstage -> unstage
hard
- starge -> 丢
- commited -> 丢
- unstage -> 丢
git 合并操作总结
git merge
git merge 用来合并分支
把 feature 分支合到 master 分支
// 如果不设置第二个分支,默认是当前分支
$ git merge feature [master]`
有时候merge 后面会加上 --no-ff 或者 --ff-only 参数
-ff
ff 意思是 fast-forward, 使用 merge 时,默认会使用 fast-forward 的方式合并代码
如果合并的分支(master)是被合并分支(feature)的上游分支,则合并成功,不会产生 merge log,
如果合并的分支(master)不是被合并分支(feature)的直接上游分支(比如 master 在 checkout 出 feature 分支后,又进行了几次提交),不能使用 fast-forward 的方式合并代码,git 会进行一次三方合并(magic),如果合并成功,就会产生一个 merge log, 如果有冲突产生,则合并失败,需要解决冲突并 commit 后才能合并.
–no-ff
如果加上 --no-ff 参数,就是默认使用三方合并的方式合并,就算合并的分支(master)是被合并分支(feature)的上游分支,也会产生一个 merge log 这种做法的好处是,忠实地记录了实际发生过什么,关注点在真实的提交历史上面
–ff-only
与 --no-ff 相反,--ff-only 表示只接受 fast-forward 方式的合并,如果不能直接使用 fast-forward 合并,会合并失败并报错。
可以设置每次git pull 都rebase
git config pull.rebase true
全局:
git config --global pull.rebase true
git pull和push默认行为
设置git pull和git push默认分支,也就是设置本地分支要跟进的分支。 建立当前分支的 upstream
$ git branch -u origin/dev
=> Branch 'dev' set up to track remote branch 'dev' from 'origin'.
也可以
git branch --set-upstream-to=origin/one-branch one-branch`
例如想把本地分支的 `feature-983` 跟进远程仓库的 `feature-983` 分支, 可以进行如下操作:
`git branch --set-upstream-to=origin/feature-983 feature-983
查看对应关系
$ git branch -vv
=> dev 32cf90b [origin/dev] e23rw
master 9b04659 [origin/master] dadfa
$ cat .git/config
=> [branch "master"]
remote = origin
merge = refs/heads/master
[branch "dev"]
remote = origin
merge = refs/heads/dev
git补丁 跨git repo操作
对于在两个不同的Git仓库之间复制更改,您需要将更改从一个仓库导出并导入到另一个仓库。以下是一种可能的方法:
导出更改: 首先,在第二个Git仓库中,导出您想要复制的更改。
bashCopy code # 进入第二个Git仓库目录 cd /path/to/second/repository # 创建一个补丁文件,记录commitB的更改 git format-patch commitB_hash -1这将在第二个仓库的目录中创建一个补丁文件,其中记录了commitB的更改。
导入更改: 然后,在第一个Git仓库中,导入这些更改。
bashCopy code # 进入第一个Git仓库目录 cd /path/to/first/repository # 应用补丁文件 git apply /path/to/patchfile.patch这将将补丁文件中的更改应用到第一个仓库中。请确保将
/path/to/patchfile.patch替换为实际的补丁文件路径。
git reflog
git reflog 是 Git 中的一个非常有用的命令,用于查看仓库中的引用日志(reference logs),即分支、HEAD 和远程引用的移动历史。它可以帮助您恢复丢失的提交、分支或更改。
恢复git reset导致的丢失。先reflog,找到reset前的hash。下面命令将移动分支的 HEAD 指针和工作目录回到
git reset前的状态。git reset --hard hash