Git 命令
本文主要介绍 Git 版本控制的部分命令,顺带谈了谈 Github 多人协作以及 hexo 。
Git的几个专有名词:
- Workspace:工作区
- Index / Stage:暂存区
- Repository:仓库区(或本地仓库)
- Remote:远程仓库
git 配置 & vi 命令 & cmd
- Git 是一个分布式版本控制软件,保存历史记录,多人协作
- 相对于 SVN 更强大,用户非常多
- nice 查看模式 (:)
- 通过上下箭头键查看过长日志
- 想要退出模式按下字母Q
- vi编辑模式(Visual Interface可视化接口)
- **vi 文件名(或者vim 文件名)**:进入文件编辑区域
- vi默认是命令模式,输入
u可以撤销,ctr+r表示恢复撤销 - 输入
i表示 insert ,可以进入编辑模式 Esc:退出编辑模式:w 回车:保存:q:退出:q!:修改后不保存,强制退出- 输入
:wq表示编辑完毕保存并退出
- cmd 命令:
dir查看当前目录所有文件
git 操作
ls:查看当前目录所有文件ls -a:查看所有文件,包括隐藏文件cd ~:返回到当前用户目录cd ..:必须空格..才能返回上级目录cd -:代表进入最近的切换目录(类似于git checkout -)mkdir 『文件夹名』:创建一个文件夹mkdir 『文件夹名』 && cd 『文件夹名』:新建并进入该文件夹mv 『目录1』 『目录2』:移动一个目录到另一个目录下,如果目录2不存在则重命名目录1为目录2rmdir 『空文件夹名』:删除一个空文件夹rm 『文件名』:删除指定文件rm -r 『文件夹名』:递归删除指定文件夹文件rm -rf 『文件夹名』:rm表示删除,-rf表示递归强制删除指定文件夹pwd(Print Working Directory):显示当前工作目录
git 初始化代码库
git init:在当前目录下初始化一个 git 仓库,创建版本管理仓库git init 『project-name』:创建一个目录同时初始化为Git代码库git init --bare:初始化裸仓库git clone 『url』:下载一个项目和它的整个代码历史git clone -o 『anothername』 『url』:克隆版本库同时修改默认 origin 别名git clone -b 『branchname』 『url』:克隆远程仓库某个分支git clone -b 『branchname』 『url』 『本地目录名』:在本地目录克隆远程仓库某个分支,如果没有该目录则新建
git 配置
git config --list(查看 git 配置信息 -l)git config --global --list(查看 git 全局配置信息 -global -l)git config [--global] -e编辑配置文件(全局)git config --get core.editor获取相应的配置git config color.ui true输出彩色信息git config core.ignoreCase false设置文件名大小写敏感git config push.default simple设置推送策略为 simplegit config --global core.editor vim设置 git 编辑器是 vimgit config --global alias.co checkout设置命令别名- 设置提交代码时的用户信息
git config [--global] user.name 『name』配置用户名git config [--global] user.email 『email address』配置用户邮箱
git 忽略
vim .gitignore添加本项目的忽略文件vim .git/info/exclude添加本项目的忽略文件并不把此文件纳入版本管理git config --global core.excludesfile ~/.gitignore设置全局忽略文件git update-index --assume-unchanged <file>对已加入版本管理的文件不做更改检查git update-index --no-assume-unchanged <file>对已加入版本管理的文件做更改检查
git 查看状态/提交暂存区/提交本地仓库并创建提交日志
git status:查看仓库状态,是否有改动后未提交的文件(工作区),不跟着空目录,除非在目录下新建.gitkeep文件git add 『file1』 『file2』 ...:添加指定文件到暂存区git add 『file路径』:将文件提交到暂存区git add file1 file2git add .git add --allgit add -A
git rm 『file1』 『file2』 ...:删除工作区文件,并且将这次删除放入暂存区git rm --cached 『file』:从暂存区中取消要提交的文件(停止追踪指定文件),但文件会保留在工作区git rm --cached -r js/:移除目录必须添加-r参数,表示递归移除git mv 『file-original』 『file-renamed』:改名文件,并且将这个改名放入暂存区
删除文件
在 git 中删除文件后有两个选择:
- 确实要从版本库中删除该文件,那就用命令
git rm删掉,并且git commit - 删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本 (
git checkout -- 『file』) git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。- 命令
git rm用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。
git 代码提交本地仓库并创建提交日志
git commit -m 'xxx':提交到本地仓库并创建提交日志(必须初始化 git 配置)git commit 『file』 -m 'xxx':指定文件提交到本地仓库并创建提交日志git commit -a:会先把所有已经track的文件的改动git add进来,然后提交(有点像svn的一次提交,不用先暂存)。对于没有track的文件,还是需要执行git add <file>命令git commit --amend -m 『message』:使用一次新的 commit ,替代上一次提交(修改上一次提交日志)git commit --amend 『file1』 『file2』...:重置上一次 commit ,并包括指定文件的新变化,如果你上一次提交忘了某个文件,可以通过该方式把指定文件和上一次提交合并之后作为一次提交
将文件添加到 git 版本库
git 版本控制系统分为工作区 (working directory) 和版本库 (repository)
Git 的版本库里存了很多东西,其中最重要的就是称为 stage (或者叫index) 的暂存区,还有 Git 为我们自动创建的第一个分支 master,以及指向 master 的一个指针叫 HEAD
- 用
git add把文件添加进去,实际上就是把文件修改添加到暂存区 - 用
git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支
我们创建 Git 版本库时, Git 自动为我们创建了唯一一个 master 分支,所以,现在, commit 就是往 master 分支上提交更改。
简单理解为,需要提交的文件修改统统放到暂存区,然后,一次性提交暂存区的所有修改
git 查看提交信息
git log:查看提交日志(显示永不重复的版本号)git log --pretty=oneline:在一行显示提交日志gitk:查看提交日志的图形化界面git diff:显示暂存区和工作区的差异git diff 『file』:查看文件修改git diff -w 『file』:查看代码自动合并状况git diff --cached 『file』:显示暂存区和上一个 commit 的差异git diff HEAD:显示工作区与当前分支最新 commit 之间的差异git diff HEAD -- 『file』:查看工作区和版本库里面最新版本文件的区别
git 查看各个分支之间的关系图
- 使用 git log 命令
1 | git log --graph --decorate --oneline --simplify-by-decoration --all |
- 使用 gitk 工具
gitk --simplify-by-decoration --all
git 分支操作
git branch:列出所有本地分支git branch -u:修改已存在分支的上游关联git branch -r:列出所有远程分支git branch -a:列出所有本地和远程分支git branch -vv:检查分支关联状态,查看所有本地分支并列出该分支最新的一次 commitgit branch 『branch-name』:基于当前分支创建一个新分支,仍然停留在当前分支(主分支最起码要有一次提交,才能基于主分支创建新分支)git branch -m[-M] 『old-branch-name』 『new-branch-name』: 修改本地分支的名字(-M 表示强制更改)git branch 『branch-name』 『commit』:新建一个分支,指向指定 commitgit branch --track 『branch-name』 『remote-branch-name』:新建一个分支,并与指定的远程分支建立追踪关系git checkout -b 『branch-name』 (remote)/(branch):在本地创建一个分支跟踪远程分支git checkout -b 『branch-name』:基于当前分支新建一个分支并切换到该分支git checkout 『branch-name』:切换到指定分支,并更新工作区git checkout -:在最近的两个分支之间切换git merge 『branch-name』:将指定分支合并到当前分支git cherry-pick 『commit』:选择一个commit,合并到当前分支git branch -d 『branch-name』:删除分支(注意:必须在删除的分支之外才行)git show [branch-name]:可以看出分支上的递交状况
git 删除不存在对应远程分支的本地分支
git remote show origin:查看远程仓库详细信息,看到远程分支后面stale标记的,说明已经不需要了git remote prune origin:删除没有与远程分支对应的本地分支
分支的 upstream
git branch --set-upstream master origin/next:手动建立追踪关系,指定 master 分支追踪 origin/next 分支(已过时)git branch --set-upstream-to=origin/dev 『本地分支名』:为指定分支设置 upstream 追踪远程 origin/dev 分支,如果省略本地分支名,则默认设置当前分支git branch --unset-upstream:取消当前分支的 upstreamgit branch --unset-upstream [分支名]:取消其他分支的 upstream
查看 upstream 信息,主要是查看仓库目录下 .git/config 文件
1 | $ cat .git/config |
其中[branch “分支名”]下的信息就是 upstream 信息,remote 项表示 upstream 的远程仓库名,merge 项表示远程跟踪分支名。
也可以通过 git remote show origin 查看:
1 | $ git remote show origin |
Remote branches表示远程仓库的分支,git pull表示upstream跟踪分支。
git 基于远程分支创建新的本地分支
- 基于远程分支无污染创建本地分支:
git fetch origin hotfix&git checkout -b chief_fix FETCH_HEAD,将线上分支的 HEAD 指向本地分支 - 或者
git fetch origin hotfix&git checkout -b chief_fix origin/hotfix,效果与上面一致
git 衍合
- Your branch and ‘origin/xxx’ have diverged
git rebase: 解决 git 分支出现分叉的状况,在 rebase 的过程中如果遇到冲突就解决冲突,然后git add 冲突的文件,标识冲突解决,然后再执行git rebase --continue(注意git add之后不要执行git commit)git pull衍合会合并保留双方分叉提交并形成一个新的提交,git rebase衍合会合并保留双方提交,使之看起来像没有经过任何合并一样。
git 远程同步(拉取)
git remote add 『shortname』 『url』:指定你要 push 提交到的远端仓库别名和地址(增加一个新的远端仓库)git remote rm 『shortname』:根据别名删除指定的远程仓库git remote rename 『old name』 『new name』:修改远程仓库别名- 第一次使用Git的clone或者push命令连接GitHub时,会得到一个警告:SSH警告
git pull 『remote』 『remote-branch-name』:『branch-name』:取回远程仓库某个分支的更新,与本地分支合并,如果远程分支与当前分支合并则可以省略冒号后面的部分git pull 『origin』 『next』:取回 origin/next 分支,再与当前分支合并.实质上,这等同于先做git fetch,再做git mergegit fetch origin nextgit merge origin/next或者git rebase origin/next:在本地分支 next 上合并远程 next 分支
git pull origin:本地的当前分支自动与对应的 origin 主机“追踪分支” (remote-tracking branch) 进行合并,如果当前分支只有一个追踪分支,连远程主机名都可以省略git pull:如果当前分支只有一个追踪分支,连远程主机名都可以省略.当前分支自动与唯一一个追踪分支进行合并git pull --rebase <远程主机名> <远程分支名>:<本地分支名>:如果合并需要采用rebase模式,可以使用 –-rebase 选项git pull --rebase:表示把你的本地当前分支里的每个提交(commit)取消掉,并且把它们临时保存为补丁(patch)(这些补丁放到 “.git/rebase” 目录中),然后把本地当前分支更新为最新的 “origin” 分支,最后把保存的这些补丁应用到本地当前分支上
推荐使用 fetch + merge 代替 pull
git fetch 『远程主机名』:将某个远程主机所有分支的更新全部取回本地,但是不会自动 mergegit fetch 『远程主机名』 『分支名』:取回特定分支的更新git fetch origin master:所取回的更新,在本地主机上要用”远程主机名/分支名”的形式读取。比如origin主机的master,就要用origin/master读取。即合并远程分支更新到本地分支git merge origin/master
1 | git fetch origin master |
git 远程操作(推送)
git push <远程主机名> <本地分支名>:<远程分支名>:推送本地分支到远程仓库git push:仅限于git clone下来的项目,它会默认创建一个 remote ,名字叫 origin ,所以可以直接git push,不需要指定后面的 origin 别名git remote add 『name』 『url』:添加远端仓库地址并起一个别名git remote:查看所有远端地址,默认只能看到别名git remote -v:查看所有远端地址详情git remote show 『远端地址别名』:查看某个具体的远端地址git remote show origin:查看 origin 远程仓库的所有信息,其中 Remote branches 表示远程仓库的分支,git pull表示 upstream 跟踪分支git remote rm 『远端主机别名』:删除远程主机(仓库)git remote rename 『原主机名』 『新主机名』:重命名远程主机名git push 『远端地址别名』 『要提交到的分支名称』:推送代码到对应仓库,如果远端没有对应的分支,则新建该分支,但不会设置上游git push -u 『remote』 『branch』:把本地仓库推送到远端仓库, 加上了-u参数, Git 不但会把本地的分支内容推送到远程新的分支,还会把本地分支和远程分支关联起来,在以后的推送或者拉取时就可以简化命令git push -u origin master:该命令和下一条命令功能一致,-u是下一条命令--set-upstream的缩写,表示设置上游分支,建立本地分支与远程分支的跟踪关系git push --set-upstream origin master:记住当前的远端地址别名并提交,下次提交可以直接git pushgit push -u --all:推送所有分支并设置上游git push -u --all --tags:推送所有分支及标签
git 删除远程分支
git branch -dr 『remote/branch』:删除远程分支与本地分支的跟踪关系git push --delete origin 『branch』:删除远程分支git push origin :<branchName>:推送一个空分支到远程分支,相当于删除远程分支
git 撤销/版本回退
git checkout 『file』:恢复暂存区的指定文件到工作区git checkout master(master~1/master~2) 『file』:将当前分支工作区恢复到master分支当前/前一个/前两个commit版本并暂存,可以提交并推送到远程仓库git checkout -- 『file』:丢弃工作区修改,恢复到最近一次git commit或git add状态. 这里有两种情况:- 一种是 file 自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态
- 一种是 file 已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态
git checkout -- file命令中的--很重要,没有--,就变成了“切换到另一个分支”的命令
git checkout 『commit』 『file』:恢复某个 commit 的指定文件到暂存区和工作区git checkout (7位commit字母) 『file』git checkout .:放弃暂存区的文件修改,恢复到工作区初始状态git reset 『file』:重置暂存区的指定文件,与上一次 commit 保持一致,但工作区不变git reset HEAD file:可以把暂存区的修改撤销掉 (unstage) ,重新放回工作区,工作区内容不变git reset --soft HEAD^:回滚到HEAD之前最近的一次提交,工作区不作任何改变git reset --hard HEAD^:HEAD 表示当前版本,HEAD^与HEAD^^, 版本回退太多采用HEAD~100git reset --hard:重置暂存区与工作区,与上一次 commit 保持一致git reset 『commit』:重置当前分支的指针为指定 commit ,同时重置暂存区,但工作区不变git reset --hard 『commit』:重置当前分支的HEAD为指定 commit ,同时重置暂存区和工作区,与指定commit一致git reset --keep 『commit』:重置当前HEAD为指定 commit ,但保持暂存区和工作区不变git revert 『commit』:生成一次新的 commit,需要填写提交注释,会撤销指定 commit,后者的所有变化都将被前者抵消,并且应用到当前分支git reflog:用来记录你的每一次命令git stash:暂时将为提交的变化移除,稍后再移入git stash pop
git 撤销修改总结
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file。场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考下面的版本回退总结,不过前提是没有推送到远程库。
git 版本回退总结
- HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令
git reset --hard commit_id。 - 穿梭前,用
git log可以查看提交历史,以便确定要回退到哪个版本。 - 要重返未来,用
git reflog查看命令历史,以便确定要回到未来的哪个版本。
git 代码冲突常见解决方法
error: Your local changes to the following files would be overwritten by merge: protected/config/main.php
Please, commit your changes or stash them before you can merge.
- 如果希望保留生产服务器上所做的改动,仅仅并入新配置项, 处理方法如下:
1 | git stash |
然后可以使用 git diff -w +文件名 来确认代码自动合并的情况.
反过来,如果希望用代码库中的文件完全覆盖本地工作版本. 方法如下:
1 | git reset --hard |
分支策略 Git flow
- 在项目中长期存在两个分支: master 和 develop
- 日常开发基于 develop 分支创建三个临时分支
- 功能分支:feature-功能名称,完成开发合并到 develop 分支后删除该分支
- 预发布分支:release-版本号,测试完成后合并到 develop 和 master 分支后删除该分支
- 修补bug分支:fixbug-名称,该分支是从 master 分支上面分出来的,修补结束后再合并到 master 和 develop 分支,最后删除该分支
git 每次 clone/pull/push 都要输入密码解决方案
- 进入项目路径下
- 输入
git config --global credential.helper store - 然后,打开
.gitconfig文件,发现下面代码,以后提交克隆输入一次用户名密码就ok了
1 | [credential] |
如果没解决则可能是 git 开启了双因子控制,通过以下命令解决:
1 | git remote -v |
github
git push origin 【空格】【冒号】【你的分支名字】: 删除github上的远程分支- Github 可以让你使用社交化的方式进行编程协作,免费在线托管你的仓库,实现多人合作
- 多人协作
- Pull Request
- Collaborators
- 项目页面->Settings->Collaborators->添加协作者
- 协作者会收到一封email,然后点进去收到的邮件同意成为协作者
github pages 配合 hexo
- github 免费提供一个静态资源托管服务
- 新建一个仓库
- 仓库名必须是: 你的
github用户名.github.io
- 仓库名必须是: 你的
hexo
- 安装:
npm install hexo-cli -ghexo-cli是hexo的命令行模式,CLI = Command Line Interface, 官网推荐用户只安装一个hexo-cli即可. 在执行hexo init blog和npm install的时候,hexo-cli会自动安装hexo到博客的node_modules目录下. 另外,hexo-cli安装后, 命令行的命令叫做 hexo, 这其实只是一个别名而已……
- 初始化:
hexo init blog hexo server: 用于启动服务器, 主要用于本地预览hexo new 文章名称(不用加后缀名.md, 它会自动加)hexo generate: 生产静态文件, 该命令会把所有 md 文件以及其他资源生成到 public 目录中, 生产结束之后可以把 public 丢到一个 web 容器中, 就可以直接访问了, 不需要依赖于 hexo 了- 假如以后新增了一篇文章,使用
hexo generate命令重新生成该目录
hexo常用命令(# 后面是注释)
hexo g# 完整命令为hexo generate,用于生成静态文件hexo s# 完整命令为hexo server,用于启动服务器, 主要用来本地预览hexo d# 完整命令为hexo deploy,用于将本地文件发布到github上hexo n# 完整命令为hexo new,用于新建一篇文章