Features
Git简介
Git是最优秀的分布式版本控制系统。
每个人都可以从中心版本库中克隆到本地,以多分支的形式进行各种合作开发。
使用git help
查看基本的帮助文档,并在使用前配置好账户
git config --global user.name 'Your Name' git config --global user.email 'Your Email'
Git仓库
有两种方式获取到Git仓库,一是从本地文件中自己创建,再者,从服务器拉取一个Git仓库。
创建仓库
Git仓库是存放数据快照的地方,可以根据这些快照对数据进行修改、还原等操作。我们可以很轻松的创建一个仓库。
git init
在当前目录下会生成一个.git子目录,就是Git仓库。
克隆仓库
通常我们需要和别人一起开发,或是会查看一些开源的代码,这时候我们就需要克隆一个已有的仓库到本地。
git clone [url]
url地址一般有SSH和HTTPS的方式,使用HTTPS的话,每次进行一些操作,比如
pull
、push
等都需要输入用户名和密码,但对于别人的项目一般都是使用这种方式,也就是我们只是查看项目的源码;使用SSH的话,就不需要每次输入密码了,前提就是配置好SSH Key。
远端仓库
与远端仓库进行交互,首先需要生成一个SSH公钥,公钥默认在主目录下的~/.ssh
目录。
$ ls ~/.ssh id_rsa id_rsa.pub known_hosts
用下面的命令生成:
ssh-keygen -t rsa -C "your_email@example.com"
然后将id_rsa.pub
的内容复制到远端仓库里就大功告成了。
添加远程仓库
在远端创建一个仓库之后,需要将本地的Git仓库提交上去。基本的创建方式为:
cd /path/to/my/repo git remote add origin [url] # origin url git push -u origin --all # pushes up the repo and its refs for the first time git push origin --tags # pushes up any tags
文件管理
添加提交文件
在git仓库目录下,执行echo "love git" > readme.md
来创建一个文件,之后需要添加到仓库里:
git add readme.md
与add相呼应的是commit,即提交修改。
git commit -m "add readme.md"
通常情况下,实现某些功能的时候,会有很多文件的修改,一个个的add明显是费时费力的事情。使用点的形式来一次性的添加全部文件。
git add . # 或是 git add *
对于已经在仓库里的文件若是做了修改,可以将add和commit一起执行。
git commit -am "modify readme.md"
有时候提交完之后,发现有几个文件没有提交,或是提交信息写错了,这时候可以运行带有--amend的命令:
git commit --amend
合并更新
从远端拉取最新代码,并合并到分支中:
git pull origin next:master # 取回origin主机的next分支,与本地的master分支合并
如果远程分支是与当前分支合并,则冒号后面的部分可以省略。
git pull origin next
pull
的含义是先拉取更新,再与分支进行合并,是个自动的过程,也可手动实现:
git fetch origin # 拉取更新 git merge origin/next # 合并更新
在某些场合,Git会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)。比如,在git clone的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系,也就是说,本地的master分支自动”追踪”origin/master分支。
git branch --set-upstream master origin/next
如果当前分支与远程分支存在追踪关系,git pull就可以省略远程分支名。
git pull origin
查看状态
查看当前分支的状态:
git status
可以查看简易形式,添加-s参数
git status -s
想要具体对比不同,需要使用diff命令。
git diff
diff命令后面可以添加文件路径,查看具体某个文件的改动。
对于提交记录的查看,需要使用log。
git log
log后面添加参数,会输出不同的log记录。比如:
- 添加–oneline,会以简介的log记录输出;
- 添加–decorate参数,会显示指向这个提交的所有引用;
- 添加–graph参数会以图像的形式展示提交历史的分支结构等等。
一个比较常用的选项是-p,用来显示每次提交的内容差异,比如再加上 -2 来仅显示最近两次提交:
git log -p -2
文件修改
对于已经修改的文件,想要放弃当前的修改,还原为之前的状态:
git checkout [file name]
而已经修改的文件,如果不是想放弃当前的修改,只是想暂存起来,去处理一些比较紧急的事,之后还是需要继续操作,那就需要stash命令:
git stash #处理事情 git stash pop
pop就相当于从储藏的堆栈中移除掉最后一次的stash操作。
版本回退
git reset是版本回退的基本命令,根据后面参数的不同,回退的形式也不同。
1、已经使用git add
添加到仓库的文件,想要使得他退回到add之前:
git reset HEAD [file name]
其中HEAD表示为当前的版本。
2、对于每次的log记录,想要回退到某一个log记录的时候,并且保留当前所做的修改:
git reset [commit id]
3、对于每次的log记录,想要回退到某一个log记录的时候,并且放弃之后的修改:
git reset --hard [commit id]
4、在简单的想要回退当上一个版本,无需查看commit id的形式:
git reset --hard HEAD^
也可以在后面跟数字,表示之前的第几个:
git reset --hard HEAD~5 # 表示之前第5个log
注:在zsh中使用HEAD^
的形式可能不识别,需要对字符 ^ 进行转义:
git reset --hard HEAD\^
5、有时候我们回退了,但是又想放弃这次回退,重新回到回退之前的状态,这时候就需要查看log记录,再根据log来确认想要回到那一条记录。
git reflog
分支管理
Git分支是最吸引人的特性。而且也鼓励支持使用分支。
创建分支
创建一个新的分支并且切换到新分支上去:
git checkout -b dev_branch
这条命令就相当于
git branch dev_branch #创建分支,但没切到该分支 git checkout dev_branch #切到该分支
合并分支
基本的合并命令为merge:
git merge dev_branch # 将dev_branch分支合并到当前分支
除了merge,还有一个合并的方式,为rebase:
git rebase dev_branch
二者的区别在于merge会生成一个新的节点,而rebase则不会,在有特殊需求的情况下会使用rebase。
删除分支
删除一个分支:
git branch -d dev_branch
如果分支还未合并,可能会删除不成功,可以强制删除:
git branch -D dev_branch
解决冲突
在多人同时修改统一文件的时候,会造成某一位置的多次修改,就容易产生冲突 CONFLICT
。
<<<<<<< HEAD # 本地的代码 ======= # 别人的代码 >>>>>>> [分支名]
根据实际的需求考虑那段代码是正确的,并删除这些多余的符号。
对于rebase过程中的冲突,解决完冲突之后,应按照下面的步骤来进行:
git add . # 更新内容 git rebase --continue # git会继续应用(apply)余下的补丁 # 在任何时候,可以用--abort参数来终止rebase的行动,并且分支会回到rebase开始前的状态 git rebase --abort
标签tag
对于某些重要的提交,或是到了开发的某一阶段,就需要打个标签做记录。一般情况推荐使用附注标签。
git tag -a v1.1.0 -m "add tag" #创建标签 git push origin v1.1.0 #推送到远端仓库 git push origin --tags #推送所有标签
其他
设置忽略文件
有一些系统文件,隐藏文件,或是不必要的配置文件,没必要每次都跟着提交,就可以添加忽略。在仓库下面有个.gitignore
文件,在里面添加想要忽略的文件,并将该忽略文件也提交到远端。
查看GitHub的忽略文件配置: gitignore
设置别名
经常纠结于过长的名字,还时不时的打错,那应该尝试一下设置别名。下面有一些比较好的例子:
git config --global alias.co checkout git config --global alias.br branch git config --global alias.ci commit git config --global alias.st status
比较喜欢的是一个日志的设置:
git config --global alias.last 'log -1 HEAD' #查看最后一次提交
网上有大神还有这么设置的:
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
赶紧去看看效果吧!