文章目录
简介
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zIYsgEXG-1571831159158)(3A3D84E5984647BD933D0CFFABC37842)]
远程仓库
本地仓库
缓存区
工作区
git版本切换
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wTL3eHai-1571831159159)(7716B8E90D3B487CA58CE92210D76135)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xnHxm6U9-1571831159160)(6030ABB7A4C343F2AFA33F34DAA7F5FA)]
git的版本管理是一个链表的结构,在版本checkout的时候,会读取并覆盖本地缓存区和工作区。读取并覆盖一般有三种情况。
情况1 | 情况2 | 情况3 |
---|---|---|
当前状态与切换后的状态相同,无变化 | 当前状态存在但下一状态不存在,会读取并删除 | 当前状态不存在,但下一状态存在,会增加该文件 |
基本命令
git diff commit-id1 commit-id2 --stat
这个指令可以看两个版本之间有哪些文件改动
git diff branch1 branch2 --stat
这个指令可以看两个分支之间有哪些文件差异
git diff tag1 tag2 --stat
这个指令可以看两个tag之间有哪些文件差异或者改动
git log -p file
可以看到具体一个文件的历史改动记录
git克隆指定分支的代码
git clone -b 分支名仓库地址
git clone -b v2.8.1 https://git.oschina.net/oschina/android-app.git
Git-查看远程分支、本地分支、创建分支
查看分支
git branch
git branch -r
git branch -a
删除分支
删除远程分支
git push origin --delete ydk
删除本地分支(在其他分支环境删除ydk分支)
git branch -d ydk
创建分支
本地创建
git checkout -b ydk
git branch ydk
Git 从master拉取代码创建新分支
git checkout master
git pull
git checkout -b dev
git push origin dev
切换分支获取代码
git checkout -b myRelease origin/Release
-b 是否创建新分支
合并分
将ydk分支上传到master分支
先检出项目到一个文件夹
git clone
你检出的项目默认是master,所以现在要查看远程全部分支
git branch -a
切换分支 (切换远程origin/ydk分支到本地ydk分支)
git checkout ydk
//Branch 'ydk' set up to track remote branch 'ydk' from 'origin'.
- 如果没有报错,那就直接提交代码git push origin v1.2
- 如果报错,基本是冲突了(比如):
CONFLICT (content): Merge conflict in app/src/main/AndroidManifest.xml Auto-merging app/build.gradle CONFLICT (content): Merge conflict in app/build.gradle Automatic merge failed; fix conflicts and then commit the result.
- 你需要去到提示的文件里把git自动标注的版本冲突注释掉,看你具体需要的功能进行删减
- 然后把冲突的文件git add,和commit
,比如你有2个冲突文件,多文件add的时候直接空格隔开
最后再commitgit add app/src/main/AndroidManifest.xml app/build.gradle
git commit -m "解决2个分支之间的冲突"
提交代码
git push origin master
更新分支上的代码
git fetch
git fetch origin ydk
git merge origin/ydk
git pull
撤消上一次commit的内容
(该操作会彻底回退到某个版本,本地的源码也会变为上一个版本的内容)
git reset --hard
以下表示要撤消“update build gradle configuration file”这一次的commit id,返回到"add battery settings ui"这一次的commit id,
xp.chen@YC-JG-YXKF-PC27 MINGW64 /f/ob ((c8303a9...))
$ git log
commit c8303a9e8db2bcf4edb7488e722a380f4e8858ec (HEAD)
Author: xp.chen <xp.chen@yuneec.com>
Date: Sat Oct 28 09:28:51 2017 +0800
update build gradle configuration file
Change-Id: I9ee532fd0d4698613698a64eb754fb98a8559e32
commit 8d8e5ccf24cf6836ab780aa3860270c3876e825a
Author: xp.chen <xp.chen@yuneec.com>
Date: Sat Oct 28 09:02:01 2017 +0800
add battery settigns ui
Change-Id: Ia907ee4e84f54c00a186d31378a7925a6adaba0e
xp.chen@YC-JG-YXKF-PC27 MINGW64 /f/ob ((c8303a9...))
$ git reset --hard 8d8e5ccf24cf6836ab780aa3860270c3876e825a
HEAD is now at 8d8e5cc add battery settigns ui
xp.chen@YC-JG-YXKF-PC27 MINGW64 /f/ob ((8d8e5cc...))
$ git log
commit 8d8e5ccf24cf6836ab780aa3860270c3876e825a (HEAD)
Author: xp.chen <xp.chen@yuneec.com>
Date: Sat Oct 28 09:02:01 2017 +0800
add battery settigns ui
Change-Id: Ia907ee4e84f54c00a186d31378a7925a6adaba0e
git删除
删除远程仓库的文件或目录
git rm -r --cached a/2.txt //删除a目录下的2.txt文件 删除a目录git rm -r --cached a
git commit -m "删除a目录下的2.txt文件"
git push
删除本地分支
git branch -d 分支名
删除远程分支
git push origin --delete 分支名
git查看文件改动记录
git diff origin/master origin/ydk
查看两个远程分支之间的不同
git diff commit-id1 commit-id2 --stat
这个指令可以看两个版本之间有哪些文件改动
git diff branch1 branch2 --stat
这个指令可以看两个分支之间有哪些文件差异
git diff tag1 tag2 --stat
这个指令可以看两个tag之间有哪些文件差异或者改动
git log -p file
可以看到具体一个文件的历史改动记录
git pull和git fetch的区别:
首先在作用上他们的功能是大致相同的,都是起到了更新代码的作用。
.git/refs/head/[本地分支]
.git/refs/remotes/[正在跟踪的分支]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MflJErZD-1571831159160)(3761FF66A04B496E90613F4A8B73EF93)]
首先假设我们本地仓库的 master 分支上 commit ID =1 ,orign/mastter中的commit ID =1 ;这时候远程仓库有人更新了github ogirn库中master分支上的代码,新的代码版本号commit ID =2 ,那么在github上 orign/master的commitID=2,然后我们要更新代码。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7eVUlZrk-1571831159161)(54931C060B2E4398B30569191736335D)]
1.git fetch
使用git fetch更新代码,本地的库中master的commitID不变,还是等于1。但是与git上面关联的那个orign/master的commit
ID变成了2。这时候我们本地相当于存储了两个代码的版本号,我们还要通过merge去合并这两个不同的代码版本,如果这两个版本都修改了同一处的代码,这时候merge就会出现冲突,然后我们解决冲突之后就生成了一个新的代码版本。
这时候本地的代码版本可能就变成了commit ID=3,即生成了一个新的代码版本。
git fetch origin master : ydk
git diff origin ydk
git merge ydk
从远程获取最新的版本到本地的test分支上
之后再进行比较合并
2.git pull
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8DapXzPl-1571831159161)(6E45F3D2B07247309B401AF18746C3A2)]
使用git pull的会将本地的代码更新至远程仓库里面最新的代码版本
3.总结
不要用git pull,用git fetch和git merge代替它。
git pull的问题是它把过程的细节都隐藏了起来,以至于你不用去了解git中各种类型分支的区别和使用方法。当然,多数时候这是没问题的,但一旦代码有问题,你很难找到出错的地方。看起来git pull的用法会使你吃惊,简单看一下git的使用文档应该就能说服你。
将下载(fetch)和合并(merge)放到一个命令里的另外一个弊端是,你的本地工作目录在未经确认的情况下就会被远程分支更新。当然,除非你关闭所有的安全选项,否则git pull在你本地工作目录还不至于造成不可挽回的损失,但很多时候我们宁愿做的慢一些,也不愿意返工重来。
merge
远程分支master有文件更新,需要更新到远程ydk分支
origin/master
origin/ydk
在ydk分支:git merge master --allow-unrelated-histories
添加
创建远程仓库
git checkout -b ydk
git push origin ydk (自动在远程仓库中创建ydk)
例子
删除或修改文件
删除master中的mastertest文件
在删除mastertest文件的master文件夹
git rm mastertest
git commit -m ''
进入需要更新的文件夹
进入到master
git fetch
git merge
git 取消commit
还没有push,只是在本地commit
git reset --soft|--mixed|--hard <commit_id>
git push develop develop --force (本地分支和远程分支都是 develop)
这里的<commit_id>就是每次commit的SHA-1,可以在log里查看到
- –mixed 会保留源码,只是将git commit和index 信息回退到了某个版本.
- –soft 保留源码,只回退到commit信息到某个版本.不涉及index的回退,如果还需要提交,直接commit即可.
- –hard 源码也会回退到某个版本,commit和index 都会回退到某个版本.(注意,这种方式是改变本地代码仓库源码)
当然有人在push代码以后,也使用 reset --hard <commit…> 回退代码到某个版本之前,但是这样会有一个问题,你线上的代码没有变,线上commit,index都没有变,当你把本地代码修改完提交的时候你会发现全是冲突…这时换下一种
commit push 代码已经更新到远程仓库
对于已经把代码push到线上仓库,你回退本地代码其实也想同时回退线上代码,回滚到某个指定的版本,线上,线下代码保持一致.你要用到下面的命令
git revert <commit_id>
revert 之后你的本地代码会回滚到指定的历史版本,这时你再 git push 既可以把线上的代码更新。
注意:git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit,看似达到的效果是一样的,其实完全不同。
- 第一:上面我们说的如果你已经push到线上代码库, reset 删除指定commit以后,你git push可能导致一大堆冲突.但是revert 并不会.
- 第二:如果在日后现有分支和历史分支需要合并的时候,reset 恢复部分的代码依然会出现在历史分支里.但是revert 方向提交的commit 并不会出现在历史分支里.
- 第三:reset 是在正常的commit历史中,删除了指定的commit,这时 HEAD 是向后移动了,而 revert是在正常的commit历史中再commit一次,只不过是反向提交,他的 HEAD 是一直向前的.
git合并多个commit压缩成一个点
从HEAD版本开始往过去数3个版本
git rebase -i HEAD~3
指名要合并的版本之前的版本号
git rebase -i 3a4226b
请注意3a4226b这个版本是不参与合并的,可以把它当做一个坐标
将pick改为squash或者s,之后保存并关闭文本编辑窗口即可。改完之后文本内容如下:
pick 3ca6ec3 '注释**********'
s 1b40566 '注释*********'
s 53f244a '注释**********'
然后保存退出,Git会压缩提交历史,如果有冲突,需要修改,修改的时候要注意,保留最新的历史,不然我们的修改就丢弃了。修改以后要记得敲下面的命令:
git add .
git rebase --continue
如果你想放弃这次压缩的话,执行以下命令:
git rebase --abort
如果没有冲突,或者冲突已经解决,则会出现如下的编辑窗口:
# This is a combination of 4 commits.
#The first commit’s message is:
注释......
# The 2nd commit’s message is:
注释......
# The 3rd commit’s message is:
注释......
# Please enter the commit message for your changes. Lines starting # with ‘#’ will be ignored, and an empty message aborts the commit.
输入wq保存并推出, 再次输入git log查看 commit 历史信息,你会发现这两个 commit 已经合并了。
查看两个分支不同
比较本地分支的话,直接git diff branchA branchB
远程分支的话,git diff branchA remoteB/branchB
有时候需要更新一下本地仓库,再进行操作
# 获取远端库最新信息
$ git fetch origin
# 做diff
$ git diff ydk remotes/origin/ydk