1.下载远程分支代码
git clone git@XXXX.git master分支
git checkout -t origin/dev 非master分支(前提应该是本地已经有仓库,好像要git pull一下先)
git fetch origin tag tagname 远程tag
2.查看分支
git branch -a 所有分支,包括本地和远程
git branch -r 远程分支
git branch 本地分支
3.新建分支
git branch dev 创建本地分支,留在当前分支
git checkout -b dev 创建本地分支,切换到Dev新分支
git push origin branch:remoteBranch 创建远程分支(推送,如果不存在会新建)
4.切换分支
git checkout dev 切换本地分支到Dev
git checkout tags/tagname 切换到本地tag
5.远程分支与本地分支建立关系
git branch --set-upstream [branch] [remote-branch]
6.删除分支
git push origin --delete dev 删除远程分支dev
git push origin :dev 远程分支,推送那个一个空分支相当于删除远程分支
git branch -D dev 删除本地分支
git branch | xargs git branch -d 删除除当前分支外的本地所有分支
git branch | xargs git branch -D 强制删除除当前分支外的本地所有分支
git branch |grep cron | xargs git branch -D 强制删除分支名称包含cron字样的所有本地分支
7.将本地代码推送到远程仓库
git init 初始化本地仓库
git add . 将所有文件存储在暂存区
git commit -m "first commit" 将文件提交到本地仓库
git remote add origin http://github.com .git 与远程仓库建立关联
git push -u origin master 推送本地代码到远程仓库
8.合并
$ git branch
* A
B
$ git checkout B message.html message.css message.js other.js
$ git status
# On branch A
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: message.css
# new file: message.html
# new file: message.js
# modified: other.js
#
合并完成
注意:在使用git checkout某文件到当前分支时,会将当前分支的对应文件强行覆盖
这里新增文件没问题,但是A分支上原有的other.js会被强行覆盖,如果A分支上的other.js有修改,在checkout的时候就会将other.js内容强行覆盖,这样肯定是不行的
git merge dev 合并dev分支到当前分支
9.查看文件状态
git status 仓库当前状态
git log 当前分支的版本历史
10.回退版本
git reset --hard HEAD^
说明:在Git中,用HEAD表示当前版本,上一个版本就是HEAD^,上上一个版本就是HEAD^^,以此类推,如果需要回退几十个版本,写几十个^容易数不过来,所以可以写,例如回退30个版本为:HEAD~30。
如果你回退完版本又后悔了,想回来,一般情况下是回不来的,但是如果你可以找到你之前的commit id的话,也是可以的,使用如下即可(commit id可以在git log中找到)
git reset --hard + commit id
在Git中,版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向回退的版本,然后顺便刷新工作区文件
10.合并分支的用处有紧急修复,正常流程在主分支上新建一个分支开发新功能,这时候如果线上有Bug ,在主分支又创建一个分支hotfix,修改bug 并合并到master,看下面介绍文章有新发现,这个合并会把master指针直接指向hotfix,当新功能开发完毕要合并到主分支时,这个时候的主分支已经不是当时新创建功能分支时候的主分支了,已经合并了hotfix,这个时候的合并就有意思了,可以看文章,有可能会有冲突,然后解决冲突合并成功,这个时候的主分支合并是有策略的,会创建一个新分支,指针指向他,具体看文章,把以前的困惑解答了
分支创建与合并
看文章时应该重点理解每个分支名其实就是指针,指向不同的提交版本,后退或者提交都会促使指针移动,就像有很多对象在封装在内存里,外界有几个指针在里面指来指去,重点看指针的移动
廖雪峰讲的也挺好
合并方式有默认的fast-forward和普通模式,合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并(跟直接在分支上修改提交看起来一样),看廖雪峰博客讲的超好,以前没看懂,今天看的好清爽,git真的做的简单清爽
多人协作合并讲的也非常好(为啥以前在做项目时候看不懂呢?现在就都恍然大悟呢),当两个人都从远程相同分支拉取代码后,如果有一个人先把修改后代码上传,这个时候远程分支指针应该往后移位了,这个时候另一个人再推送会失败,原因是当前本地分支已经落后于远程分支,需要先pull最新分支在推送,拉取的时候可能会有冲突(如果两个人改了同一个地方)手动解决(git status看那个文件有问题,去修改),然后提交推送
11.暂存
git stash 要去其它分支,本分支还没处理完,先暂存到暂存区,回来继续
git stash pop 处理完其它分支,将暂存区暂存内容恢复,继续处理
11.在不带任何参数的情况下,“git diff” 会为我们给所有在本地副本中还未被打包(unstaged)的变化做个比较,并显示出来。
12.git 中几个重要名词工作区,暂存区,版本库
工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区
图片解释如下 add将文件修改放在暂存区,commit将暂存区文件全部提交到当前分支
13.回退
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file。
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD ,就回到了场景1,第二步按场景1操作。
场景3:已经推送到了远程,想要回退
//找到要回退的commitId
git log
//本地强制回滚
git reset --hard commitId
//强制推送到远端
git push -f
14.git status 返回3个内容
当前所在分支
和远程分支的最新关系
文件情况
15.untracked说明是新文件
以前有的文件修改了,显示的是changes not staged for commit
已经加入暂存区了,显示的是 changes to be committed
16.git diff --staged
比较暂存区和上一次commit的区别
git log -1 只返回最近的1个commit
git log --online 只返回commit ID 和 message 简化直观
git log --stat 返回更详细
git log --patch 返回超级详细,还有文件diff
18.想要在git中删除一个文件,但本地保留,比如说.idea文件夹,用git rm -r .idea(-r是文件夹递归删除,文件不需要),然后git commit && git push 即可;想要本地也删除直接rm file
想要不追踪一个文件,不被Git控制,但是不彻底删除,留在本地项目里面,这个命令会在工作区保留文件,暂存区没有 git rm --cached filename 执行完上面命令,git status 这个文件的状态是untraceked file,如果切分支会提示有文件未提交,加入到Git或者删除,可以git stash暂存
19很好用的网站,模拟Git分支行为 git-school.github.io/visualizing…
20git checkout -b new_branch 的时候,如果当前分支暂存区有未commit的文件,切换到new_branch之后git status可以看到还是会有这些未commit的文件,不同分支暂存区是共用的,这也是为什么不小心在本地master分支写了一些代码,切换到新分支还是会有这些代码
git stash list 简单展示
git stash show 详细信息
22 git reset --soft commit ID 之后的变更从仓库回到暂存区,这种情况可能是需要删掉一些修改或者增加一些修改然后在提交
git reset --mixed 也是默认reset 相当于 git reset 所有commit id 之后的改变回到工作区
git reset --hard 直接丢弃commit ID之后的变更,这个选项会把工作区和暂存区的更改也丢掉
23.merge 能够保存版本的历史信息
rebase看起来更干净,但是信息不准确,黄色节点可能和蓝色是同时发生的,rebase会变成一条直线
24.tag和branch内部都是一个commit ID,但是tag不会移动,branch会随着代码提交往前移动
25本地修改了之后,和远程有冲突
相当于
背景 远程和本地master不一致
1.git fetch把远程master下载到本地,
2.本地merge远程分支,产生一个commit,合并了本地和远程分支
3.git push到远程,远程的commit信息也更新了,和本地保持一致
git fetch + git merge = git pull
26
git show-ref master 查看master的本地和远程分支commit 信息,如下
27 git branch -m newname 给当前分支重命名
28
git diff是比较工作区还没有提交的和在暂存区的区别
git diff --cached 比较暂存区和repo里面的区别
29
30如果删掉branch2,红框中的两个commit就UNreachable了,Git会垃圾回收把这两个commit删掉
31.git里面index是二进制文件,不能直接打开
红线的话说明index和repository内容一样,(而不是index里面是空的)
32git checkout 会把工作区和暂存区更新和切换的分支一致
33.git reset 选项参数区别
git reset --hard 把切换后的repo的数据复制到工作区和暂存区
git reset --mix 相当于 git reset 只把数据复制到暂存区
git reset --soft 只是切换repo
34git reset 记住两个步骤 1把head指针指向reset的commit,2复制repo的数据到工作区和暂存区(根据参数而定)(其实还有3把当前commit之后的commit垃圾回收)
35 reset使用场景
有一个变更已经提交到了暂存区,工作区和暂存区都是变更过的文件,现在想要暂存区回退到和repo一样的版本,使用 git reset head 首先会回退版本,head指向的commit就是当前的commit所以回退版本这一步不会发生变化,然后因为没带参数相当于--mix,复制数据会把repo的数据复制到暂存区,这样暂存区就和repo保持一致了
如果想要完全丢弃变更,可以用 git reset --hard head 三个地方就保持一致了
git reset head如果有两个文件变更了,只想修改一个文件,后面加上文件名即可,git reset head a.txt
git reset --hard head 不能直接在后面加文件名,一般想要修改文件用git checkout
这个命令只会复制数据,不会移动commit,git checkout head a.txt 会把repo的a.txt复制到工作区和暂存区
36git stash 会把1当前变更放在stash里,2然后把repo数据复制到工作区,暂存区
36 git blame 文件路径 显示文件的前世今生
37 git log --graph --oneline 比较好看的提交展示
38 在没上传自己的commit之前可以先整理一下,把没用的暂时的commit去掉
39 git reflog 显示head的足迹,包括从哪一个分支切换到哪一个分支
40git的配置有本地,全局和系统三个地方,对于单个repo可以在本地设置
41git 远远不止是用来备份的,云端存储,多人协作
42冲突虽然很麻烦,但是最好还是经常合并,这样冲突较小比较好合
43
git缺点
一旦有了权限,所有的文件都能修改,没有文件级别的权限
44 git 核心是一个map key是sha1 value是对应的内容