学习了一下git,在这儿记录一些常用命令,不用每次查
项目结构(.gitignore LICENSE README.md…)的了解
常用命令
提交
添加到暂存区:git add XX.txt
提交到仓库:git commit -m "注释"
查看当前状态:git status
查看更改项:git diff XX.txt
查看当前文件内容:cat .XX.txt
$ cd 目录
$ git add text.txt //添加text文件到暂存区(需要手动新建)
$ git commit -m "注释" //将文件提交到仓库(可一次提交多个)
$ git status //查看是否有未提交(已修改但没提交)
$ git diff text.txt //看到底改了什么内容
版本回退
显示提交日志:git log
或git log --pretty=oneline
回退到前版本:git reset --hard HEAD^
退回到未来:git reset --hard 版本号
查看版本号:git reflog
$ git log //显示从最近到最远的提交日志
$ git log --pretty=oneline //好看一点
$ git reset --hard HEAD^ //一个^回退一个版本 上一个为HEAD^ 上100个版本为HEAD~100
$ cat .test.txt //看当前文件内容(就是上一版本的内容了)
//回退
$ git reset --hard 1094a //1094a为版本号(几个就行)
$ git reflog //查看版本号(记录每一次命令)
撤销修改
撤销工作区的修改:git checkout -- XX.txt
撤销暂存区的修改:git reset HEAD XX.txt
(后还需要接撤销工作区的修改)
$ git checkout -- readme.txt //丢弃工作区的修改
$ git reset HEAD readme.txt //把暂存区的修改撤销掉(unstage),重新放回工作区(后还需要进行上一步)
删除文件
删除:rm XX.txt
(也可文件夹手动删)
删完也要提交git commit -m "remove XX.txt"
删错了(撤销工作区的修改):git checkout -- XX.txt
$ rm test.txt
$ git commit -m "remove test.txt" //删除也要commit
$ git checkout -- test.txt //删错了!(用版本库里的版本替换工作区的版本)
远程仓库(Github)
找一台电脑充当服务器的角色,每天24小时开机,其他每个人都从这个“服务器”仓库克隆一份到自己的电脑上,并且各自把各自的提交推送到服务器仓库里,也从服务器仓库中拉取别人的提交。
于是——
- 运用Github添加SSH Key
每台电脑都可以搞一次
$ cd ~/.ssh //查看是否配置过密钥
$ ssh-keygen -t rsa -C "email@example.com" //创建ssh(之后不断enter就行)
$ cat ~/.ssh/id_rsa.pub //查看你生成的公钥
//也可到用户主目录里.ssh目录,有id_rsa(私钥)和id_rsa.pub(公钥)两个文件
- 登陆GitHub,打开“Account settings”,“SSH Keys”页面:
然后点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容
为什么GitHub需要SSH Key呢?
因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。
GitHub允许你添加多个Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的Key都添加到GitHub,就可以在每台电脑上往GitHub推送了。
在GitHub上免费托管的Git仓库,任何人都可以看到(但只有你自己才能改)。如果不想让别人看到Git库,一个是交点保护费,让GitHub把公开的仓库变成私有的,这样别人就看不见了(不可读更不可写)。另一个办法是自己动手搭一个Git服务器。
如果使用https很简单,基本不需要配置就可以使用,但是每次提交代码和下载代码时都需要输入用户名和密码。
本地关联并推送到远程库(先有本地库)
本地关联库:git remote add origin git@github.com:red-pitaya/XX.git
或git remote add origin https://gitee.com/relu-liana/gitme.git
远程推送:git push origin master
(也可以推送其他分支)
第一次送:git push -u origin master
查看远程库信息:git remote -v
先在github中建一个仓库learngit
$ git remote add origin git@github.com:red-pitaya/learngit.git
//在本地关联自己Github上git@github.com:red-pitaya/learngit.git远程库,并创建别名为origin
//(添加后,远程库的名字就是origin(默认))
$ git push -u origin master //第一次把本地库当前分支master推送到远程。(远程库为空)
$ git push origin master //以后每次把本地master分支的最新修改推送至GitHub
从远程库克隆(先有远程库)
远程库克隆:git clone git@github.com:red-pitaya/XX.git
在github中已有一个仓库gitskills
$ git clone git@github.com:red-pitaya/gitskills.git //在当前目录下克隆一个本地库gitskills
GitHub给出的地址不止一个,还可以用https://github.com/michaelliao/gitskills.git
这样的地址。实际上,Git支持多种协议,默认的git://
使用ssh,但也可以使用https等其他协议。
使用https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能用https。
分支管理
查看分支:git branch
创建分支:git branch XX
切换分支:git switch XX
或git checkout XX
创建+切换分支:git switch -c XX
或git checkout -b XX
合并某分支当前分支:git merge XX
删除分支:git branch -d XX
查看分支合并图:git log --graph
储存分支:git stash
恢复储存:git stash pop
bug复制:git cherry-pick commit
丢弃没有被合并过的分支:git branch -D name
查看远程库的信息:git remote
或git remote -v
(更详细)
$ git checkout -b dev //创建dev分支,然后切换到dev分支
$ git switch -c dev //创建并切换到新的dev分支
//git checkout加-b表示创建并切换,相当于以下两条命令:
$ git branch dev
$ git checkout dev
$ git branch //查看当前分支
* dev
master
在dev分支上正常提交,比如对readme.txt做个修改,加上一行:
Creating a new branch is quick
.
$ git add readme.txt //在dev分支上
$ git commit -m "branch test" //提交
$ git checkout master //切换回master分支
$ git switch master //直接切换到已有的master分支
Switched to branch 'master'
$ git merge dev //合并指定分支(dev)到当前分支(master)
$ git merge --no-ff -m "merge with no-ff" dev //不使用Fast forward模式,合并后分支有历史
$ git log --graph //查看分支合并图
$ git log --graph --pretty
在分支未完成时再建一个分支
$ git stash //把当前工作现场“储藏”起来(用git status查看工作区,就是干净的)
如果在master分支上修改bug:
$ git switch master //先切到master分支上
$ git switch -c issue-101 //master上新建issue-101分支
$ git add readme.txt
$ git commit -m "fix bug 101"
[issue-101 4c805e2] fix bug 101 //事件名称
1 file changed, 1 insertion(+), 1 deletion(-)
修复完成后,切换到master分支,并完成合并,最后删除issue-101分支:
$ git switch master
$ git merge --no-ff -m "merged bug fix 101" issue-101
回到dev分支:
$ git switch dev
$ git stash list //查看刚才的工作现场存到哪去了
stash@{0}: WIP on dev: f52c633 add merge
工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:
一是用git stash apply
恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;
另一种方式是用git stash pop
,恢复的同时把stash内容也删了:
再用git stash list查看,就看不到任何stash内容了:
$ git stash pop //恢复stash内容(同时删除stash)
$ git stash list //查看
可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash,用命令:
$ git stash apply stash@{0}
如果想把master上的bug在dev分支也改一下:
同样的bug,要在dev上修复,我们只需要把4c805e2 fix bug 101
这个提交所做的修改“复制”到dev分支。注意:我们只想复制4c805e2 fix bug 101
这个提交所做的修改,并不是把整个master分支merge过来。
为了方便操作,Git专门提供了一个cherry-pick
命令,让我们能复制一个特定的提交到当前分支:
$ git branch
* dev
master
$ git cherry-pick 4c805e2
[master 1d4b803] fix bug 101
1 file changed, 1 insertion(+), 1 deletion(-)
Git自动给dev分支做了一次提交,注意这次提交的commit是1d4b803
,它并不同于master的4c805e2
,因为这两个commit只是改动相同,但确实是两个不同的commit。用git cherry-pick
,我们就不需要在dev分支上手动再把修bug的过程重复一遍。
有些聪明的童鞋会想了,既然可以在master分支上修复bug后,在dev分支上可以“重放”这个修复过程,那么直接在dev分支上修复bug,然后在master分支上“重放”行不行?当然可以,不过你仍然需要git stash命令保存现场,才能从dev分支切换到master分支。
多人合作
查看远程库信息:git remote -v
;
本地新建的分支如果不推送到远程,对其他人就是不可见的;
从本地推送分支:git push origin branch-name
如果推送失败,先用git pull
抓取远程的新提交;
在本地创建和远程分支对应的分支:git checkout -b branch-name origin/branch-name
本地和远程分支的名称最好一致;
建立本地分支和远程分支的关联:git branch --set-upstream branch-name origin/branch-name
;
从远程抓取分支:git pull
如果有冲突,要先处理冲突。
多人协作的初始处理为:
添加远程仓库到本地(一个是刚创建的私有仓库,另一个是开源仓库)
· 添加私有仓库,别名为origin(master) :git remote add origin https://github.com/XX.git
(可不添加)
· 添加开源仓库,别名为 upstream(master):git remote add upstream https://开源库地址
创建本地分支并和远端分支绑定
拉取开源库(upstream)的master分支到本地(master):git fetch upstream master
此时本地工作目录是空的, 检出到 upstream/master(master) :git checkout master
在本地创建up-master分支并将工作目录切换到此分支(master):git checkout -b up-master
将本地的up-master分支和开源库(upstream)的master分支绑定(up-master):git branch -u upstream/master
将本地工作目录切换回master分支(up-master):git checkout master
将本地master分支推送到私有库(origin),即实现本地master分支和origin/master分支的绑定(master):git push -u origin master
通过上面的操作,我们的分支有了如下的对应关系:
master ===> origin/master
up-master ===> upstream/master
定期拉取upstream/master代码合并到本地master分支
切换到up-master分支(master):
git checkout up-master
拉取代码, 注意一定要先切换到up-master分支(up-master) :git pull upstream master
切换到master分支(up-master) :git checkout master
将 up-master 的代码合并到 master 分支(master):git merge up-master
合并分支的时候如果出现代码冲突,有冲突的文件会被git标红, 通过 git status 可以看到未解决冲突的文件列表,手动解决完这些冲突后再执行 git add 和 commit 进行一次常规的提交即可。
以上没有权限向开源仓库(upstream)提交代码,也没有这个需求,只需要定期更新代码并且合并到自己的项目即可。
如果觉得开源项目有需要改进的地方可以单独fork修改后提交pull request。其实也可以直接在master分支修改,只是这是私有化的代码,如果想改进开源项目还是要提交提交pull request。
多人协作的工作模式通常是:
首先,可以试图用
git push origin <branch-name>
推送自己的修改;如果推送失败,则因为远程分支比你的本地更新,需要先用
git pull
试图合并;如果合并有冲突,则解决冲突,并在本地提交;
没有冲突或者解决掉冲突后,再用
git push origin <branch-name>
推送就能成功!如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令
git branch --set-upstream-to <branch-name> origin/<branch-name>
。
创建版本库
E盘 –> git目录下新建一个learngit版本库
$ cd E:
$ cd git
$ mkdir learngit
$ cd learngit
$ pwd //显示当前的目录
/Users/michael/learngit
touch README.md //新建说明文档
变成git可以管理的仓库
$ git init
Initialized empty Git repository in E:/git/learngit/.git/
当前learngit目录下会多了一个.git的目录,这个目录是Git来跟踪管理版本的,不要手动乱改这个目录里面的文件,否则会把git仓库给破坏了
安装命令
linux上安装:
$ git
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
安装后设置姓名跟邮箱:
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
git config --global
参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然你也可以对某个仓库指定的不同的用户名和邮箱。
最后最后强推廖雪峰的官方网站 教程很详细,很适合入门
部分链接:使用多个远端仓库协作开发
GitHub多人协作简明教程