GIT在实际⼯作中的应⽤
如果没有配置需要配置
git config --list
git config --global user.email "[email protected]"
git config --global user.name "xy"
git config --list
还可以配置git显示颜⾊
git config --global color.ui true
本地分⽀学习:
master,默认分⽀
新建分⽀: git branch 分⽀名
查看本地分⽀: git branch 在输出结果中,前⾯带* 的是当前分⽀
切换分⽀: git checkout 分⽀名
(实际项⽬中,每个⼈都要在⾃⼰的分⽀上⼯作,最后再合并到如果要在master上⾯合并分⽀,如果你在某
个分⽀上⾯修改了⼀些东⻄,但没有stash,那么你切换分⽀后修改的东⻄就没有任何保存了,如果想切,
请先git stash,然后git checkout 分⽀名,等回来以后再git stash pop)
合并分⽀: git merge +分⽀名字
删除分⽀:git branch -d +分⽀名(如果分⽀没有合并不能删除)
强制删除: git branch -D +分⽀名字(如果分⽀没有合并要删除可以使⽤)
如何管理分⽀:
master分⽀应该是⾮常稳定的,也就是仅⽤来发布新版本,平时不能在上⾯⼲活;
分⽀是否推送到远程
1),master分⽀是主分⽀,因此要时刻与远程同步;
2),dev分⽀是开发分⽀,团队所有成员都需要在上⾯⼯作,所以也需要与远程同步;
3),bug分⽀只⽤于在本地修复bug,就没必要推到远程了,除⾮⽼板要看看你每周到底修复了⼏个bug;
4),feature分⽀是否推到远程,取决于你是否和你的⼩伙伴合作在上⾯开发分⽀的⽤途
修复bug时,我们会通过创建新的bug分⽀进⾏修复,然后合并,最后删除;
当⼿头⼯作没有完成⼜不想commit时,先把⼯作现场暂存,然后去修复bug,修复后,再git
stash pop,回到⼯作现场。
创建bug分⽀的流程
假设暂存现场在dev分⽀,总体流程如下:
git stash 暂存⼯作现场
(去修bug,假设bug在master分⽀上)
git checkout master
修改bug
git add .
git commit -m "fifix bug on master"
git push origin master
git checkout dev 切到dev分⽀
git stash list 会出现stash@{0}: WIP on dev: 6224937 add mergegit
git stash pop 将之前本地dev分⽀暂存的环境恢复出来
(还可以通过 git stash apply stash@{0}进⾏恢复,再删除stask内容git stash drop)
git stash list 再次查看还有暂存现场没有
⼀、查看远程分⽀
使⽤如下git命令查看所有远程分⽀:
git branch -r
查看远程和本地所有分⽀:
git branch -a
⼆、拉取远程分⽀并创建本地分⽀
⽅法⼀
使⽤如下命令:
git checkout -b 本地分⽀名x origin/远程分⽀名x
使⽤该⽅式会在本地新建分⽀x,并⾃动切换到该本地分⽀x。
采⽤此种⽅法建⽴的本地分⽀会和远程分⽀建⽴映射关系。
⽅式⼆
使⽤如下命令:
git fetch origin 远程分⽀名x:本地分⽀名x
使⽤该⽅式会在本地新建分⽀x,但是不会⾃动切换到该本地分⽀x,需要⼿动checkout。
采⽤此种⽅法建⽴的本地分⽀不会和远程分⽀建⽴映射关系。
在本地创建远程分⽀:
如果想把本地的test分⽀提交到远程仓库,并作为远程仓库的master分⽀,或者作为另外⼀个
名叫test的分⽀。
git push origin test:master // 提交本地test分⽀作为远程的master分⽀
也可以在github⽹站直接创建
建⽴远程仓库
1.初始化⼀个空的git仓库
mkdir laneyfile //新建⽬录
cd laneyfile //进⼊新建的⽬录
ls //查看
git init //初始化本地仓库
接着你可以在本地仓库做⾃⼰的⼀些项⽬
然后需要把修改的内容提交到本地仓库
git status //查看有多少⽂件需要提交
git add . //把⼯作⽂件提交到本地仓库的暂缓区
git commit -m ‘需求的提交说明’ //把暂缓区的⽂件提交到本地仓库
在本地仓库添加⼀个远程仓库,并将本地的master分⽀跟踪到远程分⽀
git remote add origin https://github.com/fly39244080/xxxxx.git. 确认你在远程仓库已经建好了
切换暂存区、⼯作区
git stash 暂存⼯作现场
git stash list 会出现stash@{0}: WIP on dev: 6224937 add mergegit
git stash pop 将暂存区的环境恢复到⼯作区
git stash list
开发步骤
⼀般⼯作流程:
(1)基于master新建⼀个⾃⼰的分⽀branchName 并切换到⾃⼰新建的分⽀ git checkout -b branchName
(2)开发你的需求,
(3)完成后需要提交⽂件, 提交⽂件
git add .
git commit -m ‘code’
git push //第⼀次提交⽤
git push --set-upstream origin 分⽀名 与远程建⽴关联
(5)在远程github上可以看到分⽀, 并发送pull request请求, 等待测试
(6)测试分⽀需求没有问题, 合并代码到master ,可以在远程通过发起的pull request 合并, 也可以在本
地通过 代码合并
如果是在本地⽤命令合并到master, 步骤如下:
确定当前在的分⽀是 master ,如果不是git checkout master ,拉取最新代码 git pull
git status 查看确保没有任何冲突
git merge 你的分⽀
git status 查看是否有冲突 ,如果有冲突先解决冲突
git push 把合并的代码提交到远程服务器
集成开发
⽐如有⼀个⽐较⼤的需求, 可能需要3个星期完成, 参与⼈是 2个⼈,集成分⽀名为:test/imgscroll
A同学
1.git checkout master
2.git pull
3.git checkout -b test/imgscroll 然后在分⽀上开发⾃⼰的需求
4.git push //分⽀提交到远程, 第⼀次提交,需要与远程发⽣关联⽤ git push --set-upstream origin 分⽀名
B同学
拉取代码:
1.git fetch //或者 git fetch origin test/imgscroll
2.git checkout test/imgscroll
3.开发
4.提交代码
git add .
git commit -m ‘code’
git push
最后项⽬开发完毕了, 需要把这个集成分⽀合并到master, 但是之前还得提交给测试去测试, 所以可以先发
送⼀个pull request请求 ,测试通过后, 就需要合并到master,可以直接通过在guthub上合并, 也可以通过A
同学,或者B同学去合并
git checkout master
git pull //拉取最新的代码,因为除了A,B同学, 还有很多别的同事也同步在开发别的需求git merge origin test/imgscroll
git push 完成合并
git常⽤操作⼩总结
git init ===== 建仓库, 初始化Git仓库
git add 说明.txt ===== 把文件(这里指“说明.txt")纳入暂存区(还没有真正纳入版本控制,需要再一步确
认)
git status =======查看工作区和暂存区状态
git commit -m '...' 提交纳入本地仓库(要写原因所以要加 -m)====git commit -m "说明内容"
注意:第一次提交需要先提交姓名和邮箱,否则会报错
git log ===== 查看提交日志
git checkout - - ====删除文件还原:
git reset -- hard 版本号 ===== 版本号码(至少写五位) 回到历史版本号版本
• 回退到上上⼀个版本:git reset ––hard HEAD^^
• 回退到上N个版本:git reset ––hard HEAD~N(N是⼀个整数)
• 回退到任意⼀个版本:git reset ––hard 版本号
补充:撤回暂存中某个文件:git reset HEAD test.txt
撤回暂存中全部文件: git reset .
git reflog
======= 回到删
除的未来版本(过
去将来时)
通过git建议不要
git init
在本地新建⼀个repo,进⼊⼀个项⽬⽬录,执⾏git init,会初始化⼀个repo,并在当前⽂件夹下创建⼀
个.git⽂件夹.
git clone获取⼀个url对应的远程Git repo, 创建⼀个local copy.
⼀般的格式是git clone [url].
clone下来的repo会以url最后⼀个斜线后⾯的名称命名,创建⼀个⽂件夹,如果想要指定特定的名称,可以
git clone [url] newname指定.
git status
查询repo的状态.
git status -s: -s表示short, -s的输出标记会有两列,第⼀列是对staging区域⽽⾔,第⼆列是对working
⽬录⽽⾔.
git log
show commit history of a branch.
git log --oneline --number: 每条log只显示⼀⾏,显示number条.
git log --oneline --graph:可以图形化地表示出分⽀合并历史.
git log branchname可以显示特定分⽀的log.
git log --oneline branch1 ^branch2,可以查看在分⽀1,却不在分⽀2中的提交.^表示排除这个分⽀
(Window下可能要给^branch2加上引号).
git log --decorate会显示出tag信息.
git log --author=[author name] 可以指定作者的提交历史.
git log --since --before --until --after 根据提交时间筛选log.
--no-merges可以将merge的commits排除在外.
git log --grep 根据commit信息过滤log: git log --grep=keywords
默认情况下, git log --grep --author是OR的关系,即满⾜⼀条即被返回,如果你想让它们是AND的关系,
可以加上--all-match的option.
git log -S: filter by introduced diff.
⽐如: git log -SmethodName (注意S和后⾯的词之间没有等号分隔).
git log -p: show patch introduced at each commit.
每⼀个提交都是⼀个快照(snapshot),Git会把每次提交的diff计算出来,作为⼀个patch显示给你看.
另⼀种⽅法是git show [SHA].
git log --stat: show diffstat of changes introduced at each commit.
同样是⽤来看改动的相对信息的,--stat⽐-p的输出更简单⼀些.
git add
在提交之前,Git有⼀个暂存区(staging area),可以放⼊新添加的⽂件或者加⼊新的改动. commit时提
交的改动是上⼀次加⼊到staging area中的改动,⽽不是我们disk上的改动.
git add .
会递归地添加当前⼯作⽬录中的所有⽂件.
git diff
不加参数的git diff:
show diff of unstaged changes.
此命令⽐较的是⼯作⽬录中当前⽂件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化
内容.
若要看已经暂存起来的⽂件和上次提交时的快照之间的差异,可以⽤:
git diff --cached 命令.
show diff of staged changes.
(Git 1.6.1 及更⾼版本还允许使⽤ git diff --staged,效果是相同的). git diff HEAD
show diff of all staged or unstated changes.
也即⽐较woking directory和上次提交之间所有的改动.
如果想看⾃从某个版本之后都改动了什么,可以⽤:
git diff [version tag]
跟log命令⼀样,diff也可以加上--stat参数来简化输出.
git diff [branchA] [branchB]可以⽤来⽐较两个分⽀.
它实际上会返回⼀个由A到B的patch,不是我们想要的结果.
⼀般我们想要的结果是两个分⽀分开以后各⾃的改动都是什么,是由命令:
git diff [branchA]…[branchB]给出的.
实际上它是:git diff $(git merge-base [branchA] [branchB]) [branchB]的结果.
git commit
提交已经被add进来的改动.
git commit -m “the commit message"
git commit --amend -m ‘commit message’. 增补提交. 会使⽤与当前提交节点相同的⽗节点进⾏
⼀次新的提交,旧的提交将会被取消.
git reset
git reset origin/master 想要恢复本地提交和远程库最新版本⼀致
undo changes and commits.
这⾥的HEAD关键字指的是当前分⽀最末梢最新的⼀个提交.也就是版本库中该分⽀上的最新版本.
git reset --hard
unstage files AND undo any changes in the working directory since last commit.
使⽤git reset —hard HEAD进⾏reset,即上次提交之后,所有staged的改动和⼯作⽬录的改动都会消
失,还原到上次提交的状态.
总结:
git reset --mixed id,是将git的HEAD变了(也就是提交记录变了),但⽂件并没有改变,(也就是
working tree并没有改变). 取消了commit和add的内容.
git reset --soft id. 实际上,是git reset –mixed id 后,⼜做了⼀次git add.即取消了commit的内
容.
git reset --hard id.是将git的HEAD变了,⽂件也变了.
按改动范围排序如下:
soft (commit) < mixed (commit + add) < hard (commit + add + local working)
git revert
反转撤销提交.只要把出错的提交(commit)的名字(reference)作为参数传给命令就可以了.
git revert HEAD //撤销最近的⼀个提交.
git revert会创建⼀个反向的新提交,可以通过参数-n来告诉Git先不要提交. git rm
git rm file: 从staging区移除⽂件,同时也移除出⼯作⽬录.
git rm --cached: 从staging区移除⽂件,但留在⼯作⽬录中.
git rm --cached从功能上等同于git reset HEAD,清除了缓存区,但不动⼯作⽬录树.
git clean
git clean是从⼯作⽬录中移除没有track的⽂件.
通常的参数是git clean -df:
-d表示同时移除⽬录,-f表示force,因为在git的配置⽂件中, clean.requireForce=true,如果不加-
f,clean将会拒绝执⾏.
git stash
把当前的改动压⼊⼀个栈.
git stash将会把当前⽬录和index中的所有改动(但不包括未track的⽂件)压⼊⼀个栈,然后留给你⼀个
clean的⼯作状态,即处于上⼀次最新提交处.
git stash list会显示这个栈的list.
git stash apply:取出stash中的上⼀个项⽬(stash@{0}),并且应⽤于当前的⼯作⽬录.
也可以指定别的项⽬,⽐如git stash apply stash@{1}.
如果你在应⽤stash中项⽬的同时想要删除它,可以⽤git stash pop
删除stash中的项⽬:
git stash drop: 删除上⼀个,也可指定参数删除指定的⼀个项⽬.
git stash clear: 删除所有项⽬.
git branch
git branch可以⽤来列出分⽀,创建分⽀和删除分⽀.
git branch -v可以看⻅每⼀个分⽀的最后⼀次提交.
git branch: 列出本地所有分⽀,当前分⽀会被星号标示出.
git branch (branchname): 创建⼀个新的分⽀(当你⽤这种⽅式创建分⽀的时候,分⽀是基于你的上⼀
次提交建⽴的).
git branch -d (branchname): 删除⼀个分⽀.
删除remote的分⽀:
git push (remote-name) :(branch-name): delete a remote branch.
这个是因为完整的命令形式是:
git push remote-name local-branch:remote-branch
⽽这⾥local-branch的部分为空,就意味着删除了remote-branch
git checkout
git checkout (branchname)
切换到⼀个分⽀.
git checkout -b (branchname): 创建并切换到新的分⽀.
这个命令是将git branch newbranch和git checkout newbranch合在⼀起的结果.
checkout还有另⼀个作⽤:替换本地改动:
git checkout --<filename> 此命令会使⽤HEAD中的最新内容替换掉你的⼯作⽬录中的⽂件.已添加到暂存区的改动以及新⽂件都不
会受到影响.
注意:git checkout filename会删除该⽂件中所有没有暂存和提交的改动,这个操作是不可逆的.
git merge
把⼀个分⽀merge进当前的分⽀.
git merge [alias]/[branch]
把远程分⽀merge到当前分⽀.
解决冲突的时候可以⽤到git diff,解决完之后⽤git add添加,即表示冲突已经被resolved.
git tag
tag a point in history as import.
会在⼀个提交上建⽴永久性的书签,通常是发布⼀个release版本或者ship了什么东⻄之后加tag.
⽐如: git tag v1.0
git tag -a v1.0, -a参数会允许你添加⼀些信息,即make an annotated tag.
当你运⾏git tag -a命令的时候,Git会打开⼀个编辑器让你输⼊tag信息.
我们可以利⽤commit SHA来给⼀个过去的提交打tag:
git tag -a v0.9 XXXX
push的时候是不包含tag的,如果想包含,可以在push时加上--tags参数.
fetch的时候,branch HEAD可以reach的tags是⾃动被fetch下来的, tags that aren’t reachable
from branch heads will be skipped.如果想确保所有的tags都被包含进来,需要加上--tags选项.
git remote
list, add and delete remote repository aliases.
因为不需要每次都⽤完整的url,所以Git为每⼀个remote repo的url都建⽴⼀个别名,然后⽤git remote
来管理这个list.
git remote: 列出remote aliases.
如果你clone⼀个project,Git会⾃动将原来的url添加进来,别名就叫做:origin.
git remote -v:可以看⻅每⼀个别名对应的实际url.
git remote add origin [url]: 添加⼀个新的remote repo.
git remote rm [alias]: 删除⼀个存在的remote alias.
git remote rename [old-alias] [new-alias]: 重命名.
git remote set-url [alias] [url]:更新url. 可以加上—push和fetch参数,为同⼀个别名set不同的存取
地址.
git fetch
download new branches and data from a remote repository.
可以git fetch [alias]取某⼀个远程repo,也可以git fetch --all取到全部repo
fetch将会取到所有你本地没有的数据,所有取下来的分⽀可以被叫做remote branches,它们和本地分
⽀⼀样(可以看diff,log等,也可以merge到其他分⽀).
git pull
fetch from a remote repo and try to merge into the current branch.
pull == fetch + merge FETCH_HEAD
git pull会⾸先执⾏git fetch,然后执⾏git merge,把取来的分⽀的head merge到当前分⽀.这个
merge操作会产⽣⼀个新的commit. 如果使⽤--rebase参数,它会执⾏git rebase来取代原来的git merge.
git rebase
--rebase不会产⽣合并的提交,它会将本地的所有提交临时保存为补丁(patch),放在”.git/rebase”⽬录
中,然后将当前分⽀更新到最新的分⽀尖端,最后把保存的补丁应⽤到分⽀上.
rebase的过程中,也许会出现冲突,Git会停⽌rebase并让你解决冲突,在解决完冲突之后,⽤git add去更
新这些内容,然后⽆需执⾏commit,只需要:
git rebase --continue就会继续打余下的补丁.
git rebase --abort将会终⽌rebase,当前分⽀将会回到rebase之前的状态.
git push
push your new branches and data to a remote repository.
git push [alias] [branch]
将会把当前分⽀merge到alias上的[branch]分⽀.如果分⽀已经存在,将会更新,如果不存在,将会添加这
个分⽀.
如果有多个⼈向同⼀个remote repo push代码, Git会⾸先在你试图push的分⽀上运⾏git log,检查它
的历史中是否能看到server上的branch现在的tip,如果本地历史中不能看到server的tip,说明本地的代码不
是最新的,Git会拒绝你的push,让你先fetch,merge,之后再push,这样就保证了所有⼈的改动都会被考虑进
来.
git reflog
git reflog是对reflog进⾏管理的命令,reflog是git⽤来记录引⽤变化的⼀种机制,⽐如记录分⽀的变化或
者是HEAD引⽤的变化.
当git reflog不指定引⽤的时候,默认列出HEAD的reflog.
HEAD@{0}代表HEAD当前的值,HEAD@{3}代表HEAD在3次变化之前的值.
git会将变化记录到HEAD对应的reflog⽂件中,其路径为.git/logs/HEAD, 分⽀的reflog⽂件都放
在.git/logs/refs⽬录下的⼦⽬录中.
特殊符号:
^代表⽗提交,当⼀个提交有多个⽗提交时,可以通过在^后⾯跟上⼀个数字,表示第⼏个⽗提交: ^相当于
^1.
~<n>相当于连续的<n>个^.
git revert使⽤场景:
• //下⾯的命令只是在vi编辑命令中使⽤
• ⾸先使⽤esc(键退出)->:(符号输⼊)->wq(保存退出)
• :wq(保存编辑操作退出)
• :wq!(保存编辑强制退出)
假设⼩明在⾃⼰分⽀ xiaoming/cool-feature 上开发了⼀个功能,并合并到了 master 上,之后
master 上⼜提交了⼀个修改 h,这时提交历史如下:
a -> b -> c -> f -- g -> h (master)
\ / d -> e (xiaoming/cool-feature)
突然,⼤家发现⼩明的分⽀存在严重的 bug,需要 revert 掉,于是⼤家把 g 这个 merge commit
revert 掉了,记为 G,如下: a -> b -> c -> f -- g -> h -> G (master)
\ /
d -> e (xiaoming/a-cool-feature)
然后⼩明回到⾃⼰的分⽀进⾏ bugfifix,修好之后想重新合并到 master,直觉上只需要再 merge 到
master 即可 a -> b -> c -> f -- g -> h -> G -> i (master)
\ / /
d -> e -> j -> k ---- (xiaoming/a-cool-feature)
传超过50m的⼤⽂件, 不然git会提示报错 ,需要安装git - lfs到本机
官⽹链接:https://git-lfs.github.com/
需要⾸先安装 git-lfs