Windows10下安装Git:
https://blog.csdn.net/qq_32786873/article/details/80570783
Windows10安装Git总结:除了安装路径,全部按照默认设置。
Ubuntu16.04下安装Git
直接在命令行输入下面这句就可以了
sudo apt-get install git
Git介绍和学习使用Git:
https://git-scm.com/book/zh/v2(中文官方)
https://www.liaoxuefeng.com/wiki/896043488029600
http://gitbook.liuhui998.com/index.html(这个我没怎么看过,不过更加官方)
其他部分命令学习归纳:
https://www.cnblogs.com/ydxblog/p/7988317.html
下面记录一些常用的git命令和问题。<>中是要根据实际情况修改的变量名,[]中的是可选项。
本地基本操作。本地git有三个区:工作区,暂存区,版本库。工作区内容先存到暂存区,再将暂存区提交到版本库形成一个新版本。
//将所在目录变成一个新的git仓库。
$ git init
//将文件<filename>添加到本地暂存区。(包括新建的文件和修改的文件)
$ git add <filename>
//将当前文件夹所有文件添加到本地暂存区
$ git add .
//将暂存区内容提交到仓库/版本库,<message>为本次提交的说明,是一个字符串。
$ git commit -m <message>
//-a能省略一步git add,但是只对修改和删除文件有效,新增文件还是必须git add
$ git commit -am <message>
//查看当前git的一些状态。
$ git status
//更友好的输出格式
$ git status -sb -uno --show-stash
//版本号解释
HEAD //最新版本
HEAD^ //最新版本的上一个版本
HEAD^^ //最新版本的上两个版本,有k个'^',就是上k个版本。
HEAD~<k> //最新版本的上k个版本。这样写简洁一点
72f18f66c22eddab9bad821bde2089ac553bd613 //这是个具体样例,是个16进制数,是版本号的全写。可以简写为前几个字符,一般至少4个字符,比如72f1,可能需要输入更多。
//查看工作区和暂存区的区别。
$ git diff
//查看工作区和暂存区的文件<filename>的区别。
$ git diff <filename>
//查看工作区和版本库版本<commit_id>的文件<filename>的区别
$ git diff <commit_id> -- <filename>
//查看暂存区和版本库最新版本HEAD的区别。
$ git diff --cached
$ git diff --staged
//查看当前目录和另外一个分支的差别。
$ git diff <branchname>
//比较历史版本<commit_id1>和<commit_id2>的区别,<commit_id1>和<commit_id2>指的是两个历史版本的版本号。
$ git diff <commit_id1> <commit_id2>
//查看版本库里所有历史版本,输出的东西比较长不简洁。
$ git log
//查看版本库里历史版本,一个版本输出一行。
$ git log --pretty=oneline
//查看版本库里历史版本,格式化输出%h是版本号的前7个字符、%an是作者名,%ar或者%ad是作者修订时间(显示格式不同),%s是提交说明。
$ git log --pretty=format:"%h - %an, %ar : %s"
//查看版本库历史版本,另一种格式
$ git log --pretty=format:"%h %Cgreen%ar %Cred%an %Creset %s %C(auto)%d" -10
//查看版本库里历史版本,以分支合并图的形式给出,一个版本输出一行,仅显示版本号的前7个字符。
$ git log --graph --pretty=oneline --abbrev-commit
//查看<commit_id>版本的改动
$ git show <commit_id>
//版本回退到<commit_id>版本
$ git reset --hard <commit_id>
$ git reset --soft <commit_id> //<commit_id>应该可以换成<branch>,soft能把改动的代码合上去,并且将多个commit合并成一个
//除了hard还有mixed,soft两种选择,可以参考文章https://www.jianshu.com/p/c2ec5f06cf1a
//查看用过的git命令
$ git reflog
//撤销对暂存区文件<filename>的修改,返回到和最新版本HEAD一样
$ git reset HEAD <filename>
//撤销对工作区文件<filename>的修改,返回到和暂存区一样
$ git checkout -- <filename>
//连续使用上面两步,能使工作区和版本库最新版本HEAD的文件<filename>一样
//撤销对所有本地文件的修改
$ git checkout -f
//删除暂存区文件和工作区文件<filename>。若是版本库中没有该文件,则提示需要加参数-f来强制删除。
$ git rm <filename>
//仅删除暂存区文件<filename>,
$ git rm -cached <filename>
//可以继续使用git commit -m <message>删除版本库文件<filename>
/*
参考文献:https://zhuanlan.zhihu.com/p/27435067
git rm命令根据作用的文件的存在情况,分为三种情况:
一、暂存区中没有,提示找不到文件。
二、若是直接删除成功,则不管版本库和本地有没有文件,都将暂存区和本地的文件删除。
三、若是提示两个参数: --cached 删除暂存区,保留本地;-f 删除暂存区和本地。则说明暂存区和本地都有文件。
*/
本地仓库分支使用
//查看所有本地分支
$ git branch
//创建新分支<branchname>
$ git branch <branchname>
//切换到<branchname>分支。下面两种命令都可以。如果远程仓库不存在这个分支,则切换不成功,如果存在,则将远程仓库的该分支clone到本地。
$ git checkout <branchname>
$ git switch <branchname>
//创建并切换到<branchname>分支。下面两种命令都可以。
$ git checkout -b <branchname>
$ git switch -c <branchname>
//删除本地分支<branchname>
$ git branch -d <branchname>
//强行删除没有被合并过的分支<branchname>
$ git branch -D <branchname>
//合并分支<branchname>到当前分支,默认Fast forward模式
$ git merge <branchname>
//如果合并成功就成功了,但<branchname>不会自动删除。
//如果合并不成功,即产生冲突。Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,所以我们需要再手动打开文件修改冲突。之后才好提交到暂存区中。
//合并分支<branchname>到当前分支,强制不使用Fast forward模式。这种合并方式会同时提交一个commit
$ git merge --no-ff <branchname> -m "merge with no-ff"
//冲突解决方式和上面一样
工作现场存储和恢复(包含代码遴选介绍)
//工作现场的存储
$ git stash
//查看存储的所有工作现场
$ git stash list
//恢复某个工作现场,并删除stash中该工作现场
//方法一,其中stashname的样式为stash@{0},0可变。
$ git stash apply [stashname]
$ git stash drop
//方法二
$ git stash pop [stashname]
//代码遴选:复制一个特定的提交到当前分支
$ git cherry-pick <commit_id>
//修复bug需要用到stash功能。
//修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;
//当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场;
//在master分支上修复的bug,想要合并到当前dev分支,可以用git cherry-pick <commit_id>命令,把bug提交的修改“复制”到当前分支,避免重复劳动。
使用远程仓库。下面的origin为远程主机名,默认为origin,如果远程主机名不是这个则将origin改成应改的主机名。
//在本地主目录下创建SSH Key,生成的key在主目录的.ssh文件夹下,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,id_rsa.pub是公钥。
$ cd ~
$ ssh-keygen -t rsa -C <youremail@example.com>
//在GitHub上自己的账号里加入自己或别人的公钥,实现SSH远程传输。
登陆GitHub,在右上角点击后打开"Settings",左边选择"SSH and GPG Keys",然后右侧选择"New SSH key",填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容,最后点击"Add SSH key"。
//创建远程仓库
登陆GitHub,在右上角"+"下面选择"New Repository",填入仓库名(必填),仓库描述,选择公开或私密,选择是否初始化一个README.md文件。不初始README.md文件的话,生成空的远程仓库,可以本地直接push已有的本地仓库上去;初始化README.md文件的话,可以将该远程仓库pull下来后,从头开始建立本地仓库。
//关联本地仓库和远程仓库,最后一个参数实际就是仓库地址最后加个.git。只不过这里用ssh访问,而不是用http访问,所以地址前面的https://改为git@。如果用https访问,则地址前面不用改,只不过用https访问,之后每次提交commit都要输入仓库拥有者的账号和密码。
$ git remote add origin git@github.com:<Github_username>/<repositoryname>.git
//查看远程库信息。加-v可以查看更详细的信息。
$ git remote [-v]
//提交本地git仓库分支<branch>到远程仓库,默认初始创建分支叫master。
//第一次提交时要加上-u参数,这样Git不但会把本地的<branch>分支内容推送的远程新的<branch>分支,还会把本地的<branch>分支和远程的<branch>分支关联起来,在以后的推送或者拉取时就可以简化命令。
//第一次提交时,还会有个警告,原因缺少known_hosts文件。输入yes并回车就好了,会自动建立known_hosts文件。还有什么bug的话可以参考https://blog.csdn.net/cly141220010/article/details/106443577。
$ git push [-u] origin <branch>
//提交本地<local_branch>分支作为远程的<remote_branch>分支
$ git push origin <local_branch>:<remote_branch>
//为简化上述提交命令,可以先通过下面的命令进行设置,默认将本地的<branch>分支的推送到origin/<branch>。设置完后在<branch>分支下就可以只用git push提交了。
$ git branch --set-upstream-to=origin/<branch> <branch>
//从远程仓库克隆到本地。
$ git clone git@github.com:<Github_username>/<repositoryname>.git
//从远程拉取<remote_branch>分支。
$ git fetch origin <remote_branch>
//从远程拉取<remote_branch>分支并与本地当前分支合并。
$ git pull origin <remote_branch>
//从远程拉取<remote_branch>分支并与本地<local_branch>分支合并。
$ git pull origin <remote_branch>:<local_branch>
//查看远程仓库所有分支
$ git branch -r
//查看本地和远程仓库的所有分支
$ git branch -a
//查看本地和远程仓库的所有分支,并显示每个分支最后提交的message
$ git branch -a -v
//删除远程仓库分支<branch>。下面三种命令都可以,第二种命令实际上是将提交空分支到远程的<branch>,等于删除了远程的<branch>分支。
$ git branch -r -d origin/<branch>
$ git push origin :<branch>
$ git push origin -d <branch>
//远程仓库版本回退。先本地分支版本回退,然后用下面命令强制推送到远程分支。
$ git push -f
//更新远程仓库变更到本地
$ git remote update origin
标签
//给当前分支最新的commit打一个标签
$ git tag <tagname>
//给某个commit打一个标签
$ git tag <tagname> <commit_id>
//创建带有说明的标签,-a指定标签名,-m指定说明文字
$ git tag -a <tagname> -m <message> <commit_id>
//查看所有标签
$ git tag
//查看某个标签的信息
$ git show <tagname>
//删除标签
$ git tag -d <tagname>
//推送一个标签到远程
$ git push origin <tagname>
//推送所有标签到远程
$ git push origin --tags
//删除一个远程标签。需要两步操作。
$ git tag -d <tagname>
$ git push origin :refs/tags/<tagname>
变基
此部分参考https://blog.csdn.net/nrsc272420199/article/details/85555911
//将本地的多次提交合并成一个,以简化提交历史。本地有多个提交时,如果不进行这一步,在git rebase master时会多次解决冲突(最坏情况下,每一个提交都会相应解决一个冲突)
$ git rebase -i
//将当前分支变基到master分支上。这个过程可能需要手动解决冲突(如果进行了上一步的话,只用解决一次冲突)
$ git rebase master
具体操作流程:
//切换到master分支
$ git checkout master
//拉取最新分支状态
$ git pull
//切回local分支
$ git checkout local
//合并提交。2表示合并两个,相当于把当前提交合并到之前两次提交上去了。
$ git rebase -i HEAD~2
$ git rebase master
---->解决冲突--->
//解决完冲突继续rebase
$ git rebase --continue
//切换到master分支
$ git checkout master
//将local分支合并到master上
$ git merge local
//提交
$ git push
更多的详情和示例请见官网“https://git-scm.com/book/zh/v2/Git-分支-变基”。
一般开发中各个分支的作用:
git有个最佳实践,master是主分支,用来做正式发布版之后的保留历史,其他分支包括dev用来做正常开发,多个feature用来做某些特性功能,release用来做发布版历史,每次发布都是用release打包,hotfix用来做发布版之后的一些及时迭代修复bug的工作。
另外的,也有下面这个标准的:
Production分支(主线分支用于发版,不会直接改)
Master分支,这个分支只能从其他分支合并,不能在这个分支直接修改
Develop分支(开发分支)
这个分支是我们是我们的主开发分支,包含所有要发布到下一个Release的代码,这个主要合并与其他分支,比如Feature分支
Feature分支(新功能分支)
这个分支主要是用来开发一个新的功能,一旦开发完成,我们合并回Develop分支进入下一个Release
Release分支(偏向测试)
当你需要一个发布一个新Release的时候,我们基于Develop分支创建一个Release分支,完成Release后,我们合并到Master和Develop分支
Hotfix分支(紧急bug发布)
当我们在Production发现新的Bug时候,我们需要创建一个Hotfix, 完成Hotfix后,我们合并回Master和Develop分支,所以Hotfix的改动会进入下一个Release
多人协作的工作模式:
-
首先,可以试图用
git push origin <branch-name>
推送自己的修改; -
如果推送失败,则因为远程分支比你的本地更新,需要先用
git pull
试图合并; -
如果合并有冲突,则解决冲突,并在本地提交;
-
没有冲突或者解决掉冲突后,再用
git push origin <branch-name>
推送就能成功!
如果git pull
提示no tracking information
,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to=origin/<branchname> <branchname>
。