1,https://git-for-windows.github.io/ 下载windows 版 git
2,安装完成后,还需要最后一步设置,在命令行输入:
$ git config --global user.name "loveqin"
$ git config --global user.email “loveqin@xx.com”
3,创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Git Bash),创建SSH Key:
$ ssh-keygen -t rsa -C “loveqin@xx.com”
4,你需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可,由于这个Key也不是用于军事目的,所以也无需设置密码。
如果一切顺利的话,可以在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。
5,登陆github或者公司gitlab(source.xx.com),点击用户名到用户主页,点击个人设置,点击添加按钮,输入key的名称。
6,到根目录下,找到id_rsa.pub文件,粘贴里面的内容到上一步里的公钥处。
7,找到自己的库,点击ssh地址,然后复制。
8,gitbash 里 进入到自己的要放置项目的文件夹,运行git clone 刚刚复制的ssh的地址即可。
常用命令
git clone [url] #从远端下载一个项目。
git fetch #下载远程仓库的所有变动更新。
git pull #下载远程仓库的所有变动更新并与本地分支合并 ,相当于git fetch 后 再 git merge。
---2017-08-16补充 begin---
注:这里重点说下。git fetch 后再git merge 会发生什么?这里涉及到一会儿我们要补充git rebase.
假设有2个developer love 和 pony 同时开发一个项目。各自从远端库拉取了一份代码,并且直接在master分支上开发。
本地master以及远端master如下图:
然后love 在自己的分支上进行了开发更新了代码并且commit到了暂存区(J1)。
pony也在自己的分支上进行了开发并且commit到了暂存区(T1)。
pony 先于love首先把自己的修改push到了远程仓库,远程仓库origin/master指针指向了T1。
现在love也想把自己的提交push到远程,运行git push ,失败了。因为远端库已经更新了。然后love 运行了下git fetch ,把远端库的更新拉取到了自己的本地仓库。
如上图所以,love的本地仓库发生了分歧,有从远端库fetch过来的T1,同时也有自己本地的commit J1。这时怎么解决?想要把pony提交的T1合并到自己的仓库中来,可以使用git merge ,这个merge即包含了pony的T1,也包含了 love的 J1,但是加上之前的一次commit,会有2次commit,review的时候要比较2次,比较麻烦。并且git log里多了一次无意义的commit历史。(这前面说的,git fetch+git merge ,其实就是我们常用的git pull 帮我们做的事情)。
为了保证git commit 历史的线性和干净。我们可以采用另一种方式,git rebase。如果love在git fetch之后,没有用git merge,而是用了git rebase改变 J1的history,如下图:
rebase之后 J1 变成了J1`,其实还是刚刚的J1,只是commit 的history变了,J1的commit 码都没变(这其实就是git pull --rebase)。
然后love 也git push 到了远端库
love 的本地库
git rebase-i <commit-id>,合并或者commit提交历史。也就是可以取git log里的commit的某一些版本合并到一起。这个一般会跟接下来要说的 git cherry-pick有关系。
例如:git rebase -i fc2abeb55542b9c2e445af28bfe4c91be0eb6735
这条命令会从fc2abeb55542这个commit id 开始合并你想合并的commit成一个commit。这时要vim修改想要合并的commit 的pick 为s ,并且要留下一个commit id,将来会以这个commit id为基准,把改成s的commit提交合并到这个留下的commmit id里,产生一个新的commit记录,这个记录包括了所有的你想合并的commit。这样在其他分支里cherry-pick的时候,只需要cherry-pick这一个合并了的commit即可。
接着上面,比如,
①,你在开发完成提测后,QA测试的时候,fix了很多问题,有多次commit。但是事实上,大多数项目比较庞大或者多人同步开发的时候,可能dev分支(test环境的分支)跟master并不同步,并且可能已经分开很久了。你开发的时候,并没有从master拉取分支来开发,是从dev分支开发的。所以可能没法直接把当前分支merge到master(生产环境分支)。
②,你这次开发了很多功能, 同样有很多commit ,但是这些确是要分批发布生产环境的,也就是说,有一些提交是不能merge到master(生产环境)的。
这时,我们一般会使用cherry-pick 。
git cherry-pick <commit-id>,可以检出某分支上的一次或多次commit应用到当前分支(类似再次提交) 。
注:这个新提交的commit和原来的commit的哈希值不同,是一个新的值。但标识名相同。
我们在使用cherry-pick的时候,会发现如果像上面第①种情况还是第②种情况,我们都要cherry-pick 好多次,这特别麻烦,所以我们一般在处理这2种情况的时候需要用git rebase-i ,先把我们需要cherry-pick的所有commits记录合并成1条commit记录,然后我们cherry-pick一次即可大功告成。
在cherry-pick的时候,可能会有冲突,如果有冲突的话,git status 看到当前状态会是cherry-picking ,这时我们要去有冲突的地方解决冲突,然后保存,然后记得git add 这个新保存的文件到暂存区,再接着git cherry-pick --continue ,继续cherry-pick 到 success。
当然,如果你在cherry-pick过程中,发现有问题,想终止cherry-pick,可以用git cherry-pick --abort 来终止。
---2017-08-16补充 end---
git checkout [branchName] # 切换到指定分支,并更新workspace。如果这里的branchName是远端有但是本地没有的分支,会直接本地检出这个分支并更新。等同于 git checkout -b [branchName] origin/[branchName]。
git checkout -b [branchName] #新建一个分支,并且切换到该分支。
git add [file1] [file2] #添加指定文件到暂存区。
git add .或者 git add * #添加当前目录的所有文件到暂存区
git stash # 将工作区做的修改暂存到一个git栈中
git stash list # 查看栈中暂存列表如下图
git stash apply 暂存编号(stash@{1}) #恢复对应编号暂存到工作区。但是这次暂存还存在栈中。
git stash pop # 将栈顶的暂存恢复到工作区,并从栈中去除。
git stash clear #清空暂存栈。
git commit -m "msg" #将暂存区提交到仓库。
git diff #显示暂存区和工作区的差异。
git diff HEAD #显示工作区与当前分支最新commit之间的差异。
git diff commit-log commit-log #显示两次commit的差异。
git push origin [branchName]:[branchName] #推送当前分支到远程仓库的对应分支
git push --force #强推当前分支到远程仓库,即便有冲突。
git push --all # 推送所有分支到远程仓库
git checkout [filename] #检出远端某个文件,相当于撤销了你本地工作区这个文件的修改。
只写了一些工作中最常用到的,git 命令蛮多的,之后会有补充。
---2017-08-16补充 begin---
git branch #查看本地所有分支list
git branch -a #查看本地已经远端所有分支list
git branch -d <branchName> #删除某个分支
git branch -D <branchName> #强制删除某个分支
git merge <branchName> #合并某个分支到当前分支
git merge --abort #merge过程中终止这次merge
---2017-08-16补充 end---
---2017-08-15补充 begin---:
①,如果git项目中有一些文件是不需要提交到远端的,(例如:ide的一些配置文件.idea/ .DS_Store *.iml,前端开发常node的包文件node_modules等等)可以在git项目根目录新建一个.gitignore文件提交到远端即可。
例如:
②,有的公司因为安全原因会封禁ssh端口,这时我们pull或者push代码就会采用http的方式。但是http每次push都需要输入用户名和密码;
可以用 git config --global credential.helper cache #保存配置凭证(用户名密码)到缓存,默认15分钟后失效。
git config --global credential.helper 'cache --timeout=3600' # 保存配置凭证到缓存,1小时后失效。
$ git config credential.helper store #保存配置凭证到硬盘 。这样保存的密码是明文的,保存在用户主目录下的git-credentials中,可以通过$ cat ~/.git-credentials 查看。
---2017-08-15补充 end---