https://www.liaoxuefeng.com/wiki/896043488029600/896954074659008
$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"
因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。你也许会担心,如果有人故意冒充别人怎么办?这个不必担心,首先我们相信大家都是善良无知的群众,其次,真的有冒充的也是有办法可查的。
注意git config命令的–global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
$ git commit -m "wrote a readme file"
[master (root-commit) eaadf4e] wrote a readme file
1 file changed, 2 insertions(+)
create mode 100644 readme.txt
git diff readme.txt
git log --pretty=oneline 美观显示
$ git diff HEAD -- readme.txt
diff --git a/readme.txt b/readme.txt
index 76d770f..a9c5755 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,4 +1,4 @@
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
-Git tracks changes.
+Git tracks changes of files.
首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交1094adb…(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD,上上一个版本就是HEAD,当然往上100个版本写100个比较容易数不过来,所以写成HEAD~100。
1094a 代表git log中的某一次的commit id
$ git refloge475afc HEAD@{1}: reset: moving to HEAD^
1094adb (HEAD -> master) HEAD@{2}: commit: append GPLe475afc HEAD@{3}: commit: add distributedeaadf4e HEAD@{4}: commit (initial): wrote a readme file
命令 | 解释 | 示例 |
---|---|---|
git status | 查看仓库当前的状态,看看有没有文件呗改动 | |
git diff | 查看文件修改记录 | git diff readme.txt |
命令git checkout – readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。
注:git checkout – file命令中的–很重要,没有–,就变成了“切换到另一个分支”的命令,我们在后面的分支管理中会再次遇到git checkout命令。
很重要的一点,关于删除文件,如果是工作区内误删,但没有提交,也可以使用这个命令找回文件:
git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
注意:从来没有被添加到版本库就被删除的文件,是无法恢复的!
针对于,不仅修改了工作区的内容,还使用了add命令将其放入了暂存区,但庆幸的是没有提交
删除 一些 没有 git add 的 文件;
git clean 参数
-n 显示 将要 删除的 文件 和 目录
-f 删除 文件,-df 删除 文件 和 目录
git clean -n
git clean -df
git clean -f
参考 https://blog.csdn.net/kikajack/article/details/79846098
参考 https://cnblogs.com/Super-scarlett/p/8183348.html
$ ssh-keygen -t rsa -C "[email protected]"
登陆GitHub,打开“Account settings”,“SSH Keys”页面:
然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容:
https://www.liaoxuefeng.com/wiki/896043488029600/898732864121440
要关联一个远程库,使用命令git remote add origin git@server-name:path/repo-name.git
git branch --set-upstream-to=origin/develop develop
将本地的develop分支与远程的相关联
$ git remote add origin git@github.com:michaelliao/learngit.git
关联后,使用命令git push -u origin master第一次推送master分支的所有内容;
此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改;
git clone git@github.com:michaelliao/gitskills.git
你也许还注意到,GitHub给出的地址不止一个,还可以用https://github.com/michaelliao/gitskills.git这样的地址。实际上,Git支持多种协议,默认的git://使用ssh,但也可以使用https等其他协议。
使用https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能用https。
要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。
Git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快。
https://blog.csdn.net/ypbsyy/article/details/80546796
https://www.liaoxuefeng.com/wiki/896043488029600/900003767775424
$ git checkout -b dev
Switched to a new branch 'dev'
git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
git branch命令会列出所有分支,当前分支前面会标一个*号。
git merge命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就可以看到,和dev分支的最新提交是完全一样的。
$ git merge dev # 合并dev分支到当前的master分支
$ git branch -d dev
Deleted branch dev (was b17d20e).
Git鼓励大量使用分支:
查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>
创建+切换分支:git checkout -b <name>
合并某分支到当前分支:git merge <name>
删除分支:git branch -d <name>
当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。
用git log --graph命令可以看到分支合并图。
用Q推出 git log
git merge --no-ff -m "merge with no-ff" dev
通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
准备合并dev分支,请注意–no-ff参数,表示禁用Fast forward:
因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。
合并分支时,加上–no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。
https://www.liaoxuefeng.com/wiki/896043488029600/900388704535136
$ git stash apply stash@{0} # 恢复指定的储藏
注:开发一个新feature,最好新建一个分支;
如果要丢弃一个没有被合并过的分支,可以通过git branch -D 强行删除。
$ git branch -D feature-vulcan
Deleted branch feature-vulcan (was 287773e).
$ git push origin master # 向远程仓库origin推送本地master分支
$ git push origin dev #向远程仓库origin推送本地dev分支
但是,并不是一定要把本地分支往远程推送,那么,哪些分支需要推送,哪些不需要呢?
master分支是主分支,因此要时刻与远程同步;
dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;
bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发
https://www.liaoxuefeng.com/wiki/896043488029600/900375748016320
因此,多人协作的工作模式通常是这样:
首先,可以试图用git push origin 推送自己的修改;
如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
如果合并有冲突,则解决冲突,并在本地提交;
没有冲突或者解决掉冲突后,再用git push origin 推送就能成功!
如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to origin/。
这就是多人协作的工作模式,一旦熟悉了,就非常简单。
查看远程库信息,使用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,如果有冲突,要先处理冲突。
https://www.liaoxuefeng.com/wiki/896043488029600/1216289527823648
rebase操作可以把本地未push的分叉提交历史整理成直线;
rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。
注意,使用rebase的场景是在pull完之后还没有push本地的内容
rebase 之前
$ git log --graph --pretty=oneline --abbrev-commit
* e0ea545 (HEAD -> master) Merge branch 'master' of github.com:michaelliao/learngit
|\
| * f005ed4 (origin/master) set exit=1
* | 582d922 add author
* | 8875536 add comment
|/
* d1be385 init hello
rebase 之后
$ git log --graph --pretty=oneline --abbrev-commit
* 7e61ed4 (HEAD -> master) add author
* 3611cfe add comment
* f005ed4 (origin/master) set exit=1
* d1be385 init hello
他将pull下来的f005ed4当成了本地的一次提交,放在了我还没有push的两条内容之后,因此,我们本地的commit修改内容已经变化了,它们的修改不再基于d1be385 init hello,而是基于f005ed4 (origin/master) set exit=1,但最后的提交7e61ed4内容是一致的。
使用push推送之后
$ git log --graph --pretty=oneline --abbrev-commit
* 7e61ed4 (HEAD -> master, origin/master) add author
* 3611cfe add comment
* f005ed4 set exit=1
* d1be385 init hello
https://www.liaoxuefeng.com/wiki/896043488029600/900788941487552
tag就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。其实它就是指向某个commit的指针(跟分支很像对不对?但是分支可以移动,标签不能移动),所以,创建和删除标签都是瞬间完成的。
$ git tag v1.0
$ git show v0.9
commit f52c63349bc3c1593499807e5c8e972b82c8f286 (tag: v0.9)
Author: Michael Liao <askxuefeng@gmail.com>
Date: Fri May 18 21:56:54 2018 +0800
add merge
diff --git a/readme.txt b/readme.txt
git tag -a v0.1 -m “version 0.1 released” 1094adb
用-a指定标签名,-m指定说明文字
** 注意:标签总是和某个commit挂钩。如果这个commit既出现在master分支,又出现在dev分支,那么在这两个分支上都可以看到这个标签。**
小结
命令git tag <tagname>用于新建一个标签,默认为HEAD,也可以指定一个commit id;
命令git tag -a <tagname> -m "blablabla..."可以指定标签信息;
命令git tag可以查看所有标签。
$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
* [new tag] v1.0 -> v1.0
小结
命令git push origin <tagname>可以推送一个本地标签;
命令git push origin --tags可以推送全部未推送过的本地标签;
命令git tag -d <tagname>可以删除一个本地标签;
命令git push origin :refs/tags/<tagname>可以删除一个远程标签。
https://segmentfault.com/q/1010000009850353/a-1020000009850473/revision
pull request的理解方法是:一个通知上游repo所有者拉取代码(pull)的请求(request)。
在英语中,request一般指的是提交一个申请,需要对方对申请给予答复的。而request之前的修饰词,则是答复方的动作,当然,中文中也是一样。比如“入团申请”,你提交申请之后,需要对方允许你入团你才算是团员。所以,入团的动作不是你主动做的,而是由审核的人把你的名字加上去才算“入团”。同理“pull request”中,request是你提交的,而pull则是对方做的事情。
我的总结:至于pull还是push是对最终动作的决定者而言的,而不是对动作的发起者而言的。
https://www.liaoxuefeng.com/wiki/896043488029600/900004590234208
忽略文件的原则是
忽略操作系统自动生成的文件,比如缩略图等;
忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
检验.gitignore的标准是git status命令是不是说working directory clean。
git config --global alias.st status
注意:配置Git的时候,加上–global是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用。
配置文件放哪了?每个仓库的Git配置文件都放在.git/config文件中: