git与github
- 首先
git
和github
不是同一个东西。Git
是一款免费、开源的分布式版本控制系统,而github
是基于git
的代码托管平台
且同时也具有版本记忆功能。 git
是分布式版本管理系统。git
是由linux
的创造者linus
开发的。- 不同于
CVS
和SVN
的集中式版本控制方式,git
使用分布式进行版本控制。将较而言,git
分布式版本控制可以实现本地化的版本库,工作时不必联网;git
具有强大的分支管理能力,稳定性更高。(便捷)
git首次安装后的设置
首先打开hash.exe
输入用户名和邮箱
//配置全局用户信息
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
//修改当前用户信息
$ git config user.name 你的目标用户名;
$ git config user.email 你的目标邮箱名;
利用git
本地仓库进行版本控制可以简单的理解为:a 持有实际文件的物理工作目录,b 暂存区,c 本地仓库(git在本地默认建立的一个master分支)
其中a-->b
是由add
实现,而b-->c
是由commit
实现。
利用git
在本地进行版本库存储
git
在本地指定地点建立仓库(或者是指向克隆下来的仓库):cd e:/github_projects/tisikcci.github.io
初始化一个
git
仓库:init
初始化之后,会在
tisikcci.github.io
文件夹下生成一个默认隐藏的.git
文件夹添加远程库:
在本地的learngit仓库下运行命令:$ git remote add origin 仓库地址
向这个隐藏的文件夹中添加文件:
README.md
(可以是别的文件,要将这个文件放在.git同级文件夹下):git add README.md
也可以一次添加
多个文件
,类似于:git add README1.md README2.md README3.md
将文件存入本地仓库(当前分支),同时添加改动或者说是更新说明:(
-m
后这里的‘first commit’应该是与本次提交或者更新有关系有实际意义的说明,方便以后溯源)git commit -m'first commit'
在上面的3,4步骤过程后可以使用以下命令看到内容的变动
git status
第一次提交时:`git push -u origin master`
可以使用以下代码查看git版本库的修改或者说是更新次数(使用q可以退出这个命令)
git log 如果觉得这样得到的信息太多,可以使用下面的命令,使得每次修改信息漂亮的显示在同一行 git log --pretty=oneline
也可以选定查看最近2次的版本更新信息:
git log -n 2
可以利用
reset
实现版本回退:git reset --hard head^
注意:
HEAD
表示当前版本(就是一个指针),在后面加一个^
,表示(指向)上一个版本,前第N
个版本是HEAD~N
,回退以后想恢复之前最新的版本或者是某次特定的版本,可以利用如下代码查找操作代码库的关键步骤 历史记录的ID
实现:git reflog
根据ID,比如是441736f,前进到回退前的某个版本
git reset --hard 441736f
commit
之后又对项目中的某个文件内容进行了更新,可以利用以下命令回到离commit最近的状态(就是丢弃掉没有进行add操作的更改内容,回到上次commit操作时的状态)git checkout -- 文件名
这里本质是利用本地版本库中的相同文件替换了本地文件夹中的文件,所以看起来是回到之前commit操作时的状态了(但是如果更改已经add了,除非放弃
add
操作内容,否则下次commit
又会更新本地仓库)。更进一步,撤销已经add到暂存区但没有commit到本地分支的文件git reset head 文件名
以上过程中可以使用以下命令查看具体文件的内容
cat 文件名
删除本地版本库中的文件
首先说一下一种特殊情况:本地的文件夹中的项目相关文件被删除了,但没有更新本地的版本库,如果这时想恢复被删除的项目相关文件,可以利用以下命令:git checkout -- 文件名
第二种情况是真的想删除本地仓库中的相关文件,利用以下代码删除本地文件夹中的文件(也可以手动删除)
rm 文件名
然后利用以下代码删除本地仓库中的文件
git rm 文件名
并且利用git commit进行保存
git commit -m"remove 文件名"
新建一个分支,可以利用
git branch 分支名 git checkout 分支名
上面的代码分别表示新建一个分支,并将head(指针)指向新建的指针,也可以使用下面的方式直接
实现新建一个分支并使head指向它git checkout -b 分支名
可以利用下面的命令分别查看本地分支,远程分支和所有分支,当前指向分支前会加*号
git branch<br>git branch -r<br>git branch -a
删除已经存在的指定本地分支,远程分支(注意要先将指针指向其他分支才能删除此分支)
git branch -d 分支名 git push origin :分支名
重命名分支
git branch -m 原分支名 新分支名
在新分支上提交内容,对之前的主分支
master
并不会有影响,可以利用如下方式再切换回主分支git checkout master
此时
head
会重新指向master
,将master
替换为别的分支,可以实现切换到任意指定分支将新建立的分支合并到主分支(首先要切换回主分支)
git merge 新分支
合并后,就可以利用上面给出的方法删除新分支
如果想保留新建的分支,并推送到远程仓库,可以利用
git push origin 新建的分支
可以给项目进度添加版本号,通过添加标签的方式实现
git tag 版本号
通过省略版本号可以直接查看已经添加的版本号
git tag
可以给以前的某次提交补加版本号,只要查找到之前commit操作对应的ID,比如:441736f
git tag 版本号 441736f
可以利用如下的方式实现在添加标签时添加说明
git tag -a 版本号 -m "版本说明"
可以通过以下命令查看指定版本内容
git show 版本号
删除不想要的标签
git tag -d 已经存在的标签(版本号)
可以将本地标签推送到远程仓库
git push 远程主机名(比如origin) 版本号
比如:
git push origin v1.0
将本地所有的版本号都推送到远程仓库
git push origin --tags
如果想删除远程仓库的版本号,需要进行两步
a. 首先要删除本地版本号(标签) b. 再删除远程版本号 ``` git push origin :refs/tags/版本号 ```
利用以上步骤,基本可以实现利用git本地进行操作
,以下要实现将本地git仓库同步到远程仓库(例如github,当然也可以自己在一台PC上搭建一个服务器,作为远程仓库)
利用github充当远程仓库是一种很不错的方式,git本地仓库和github可以通过SSH加密,利用多种方式进行数据传输:HTTP(s)、SSH、Git、本地协议等,前两种比较常用。
本地git仓库同步到远程仓库
要想将本地仓库同步到Github上,首先需要建立本地和Github上使用的SSH私钥和公钥,在git的
bash.exe
中输入ssh-keygen -t rsa -C “tisikcci@foxmail.com
这样在用户下的
.ssh
目录里就可以创建id_rsa
和id_rsa.pub
这两个文件,一路回车- 在电脑上生成公钥和私钥,将公钥上传到
github
上
登录Github
,找到右上角的图标,打开点进里面的Settings
,再选中里面的SSH and GPG KEYS
,点击右上角的New SSH key
,然后Title
里面随便填,再把刚才id_rsa.pub
里面的内容复制到Title
下面的Key
内容框里面,最后点击Add SSH key
,这样就完成了SSH Key
的加密 测试是否连接成功
ssh -T git@github.com
- 在
Github
上建立一个你想和本地仓库进行同名的仓库(名字相同) 利用上面的
cd...
指向本地仓库的位置,然后关联到Github
的远程仓库:git remote add origin git@github.com:tisikcci/tisikcci.github.com.git
关联好之后,可以把本地仓库中的内容推送到
Github上
的远程仓库了
在首次进行推送的时候,需要:git pull --rebase origin master(如果初始化的仓库有文件比如README要先和本地合并) git push -u origin master
此处加
-u
是用来将本地master
和远程master
进行关联的,以后再次推送就不需要再加了,origin
是远程主机的名字,可以通过以下代码来查看git remote
或者是
git remote -v
这个主机名字是可以人为指定的。首次推送之后,下次再向远程仓库
master
分支推送项目时,只需要git push origin master
上面提到可以人为指定远程主机的名字,在将远程仓库克隆到本地的时候,可以实现
git clone -o 新主机名 https://github.com/tisikcci/first-static-web-page.git/
如果使用默认的主机名并且克隆到本地指定的位置,可以利用
git clone https://github.com/tisikcci/first-static-web-page.git/
本地地址
最好是直接利用SSH
协议进行clone
,如下git clone 仓库的SSH地址 本地建立的空文件夹地址 git clone git@github.com:tisikcci/test.git e:/github_projects/zz
就将远程仓库的
test
克隆到了本地的zz
文件夹中。
远程仓库同步本地git仓库
git pull
命令
git pull
命令用于从另一个存储库或本地分支获取并集成(整合)。git pull命令的作用是:取回远程主机某个分支的更新,再与本地的指定分支合并,它的完整格式稍稍有点复杂。
使用语法
git pull [options] [<repository> [<refspec>…]]
描述
将远程存储库中的更改合并到当前分支中。在默认模式下,git pull
是git fetch
后跟git merge FETCH_HEAD
的缩写。
更准确地说,git pull使用给定的参数运行git fetch,并调用git merge将检索到的分支头合并到当前分支中。 使用--rebase,它运行git rebase而不是git merge。
示例
$ git pull <远程主机名> <远程分支名>:<本地分支名>
比如,要取回origin主机的next分支,与本地的master分支合并,需要写成下面这样 -
$ git pull origin next:master
如果远程分支(next)要与当前分支合并,则冒号后面的部分可以省略。上面命令可以简写为:
$ git pull origin next
上面命令表示,取回origin/next
分支,再与当前分支合并。实质上,这等同于先做git fetch
,再执行git merge
。
$ git fetch origin
$ git merge origin/next
在某些场合,Git会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)
。比如,在git clone
的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系,也就是说,本地的master分支自动”追踪”origin/master
分支。
Git也允许手动建立追踪关系。
$ git branch --set-upstream master origin/next
上面命令指定master
分支追踪origin/next
分支。
如果当前分支与远程分支存在追踪关系,git pull
就可以省略远程分支名。
$ git pull origin
上面命令表示,本地的当前分支自动与对应的origin主机”追踪分支”(remote-tracking branch)
进行合并。
如果当前分支只有一个追踪分支,连远程主机名都可以省略。
$ git pull
上面命令表示,当前分支自动与唯一一个追踪分支进行合并。
如果合并需要采用rebase
模式,可以使用–rebase
选项(rebase
可查看下文)。
$ git pull --rebase <远程主机名> <远程分支名>:<本地分支名>
git fetch
和git pull
的区别
git fetch
:相当于是从远程获取最新版本到本地,不会自动合并。$ git fetch origin master $ git log -p master..origin/master $ git merge origin/master
以上命令的含义:
- 首先从远程的
origin
的master
主分支下载最新的版本到origin/master
分支上 - 然后比较本地的
master
分支和origin/master
分支的差别 - 最后进行合并
- 首先从远程的
上述过程其实可以用以下更清晰的方式来进行:
$ git fetch origin master:tmp
$ git diff tmp
$ git merge tmp
git pull
:相当于是从远程获取最新版本并merge
到本地git pull origin master
上述命令其实相当于git fetch
和 git merge
在实际使用中,git fetch更安全一些,因为在merge前,我们可以查看更新情况,然后再决定是否合并。
rebase
模式
假设你现在基于远程分支"origin"
,创建一个叫"mywork"
的分支。
$ git checkout -b mywork origin
现在我们在这个分支做一些修改,然后生成两个提交(commit)
.
$ vi file.txt
$ git commit
$ vi otherfile.txt
$ git commit
//vi命令是UNIX操作系统和类UNIX操作系统中最通用的全屏幕纯文本编辑器。Linux中的vi编辑器叫vim,它是vi的增强版(vi Improved),与vi编辑器完全兼容,而且实现了很多增强功能
但是与此同时,有些人也在"origin"
分支上做了一些修改并且做了提交了. 这就意味着"origin"
和"mywork"
这两个分支各自"前进"了,它们之间"分叉"了。
在这里,你可以用"pull"
命令把"origin"
分支上的修改拉下来并且和你的修改合并; 结果看起来就像一个新的"合并的提交"(merge commit)
:
但是,如果你想让"mywork"
分支历史看起来像没有经过任何合并一样,你也许可以用 git rebase
:
$ git checkout mywork
$ git rebase origin
这些命令会把你的"mywork"
分支里的每个提交(commit)
取消掉,并且把它们临时保存为补丁(patch)
(这些补丁放到".git/rebase"目录中),然后把"mywork"
分支更新到最新的"origin"
分支,最后把保存的这些补丁应用到"mywork"
分支上。
当'mywork'
分支更新之后,它会指向这些新创建的提交(commit)
,而那些老的提交会被丢弃。 如果运行垃圾收集命令(pruning garbage collection)
, 这些被丢弃的提交就会删除. (请查看 git gc
)
现在我们可以看一下用合并(merge)
和rebase
所产生的历史的区别:
在rebase
的过程中,也许会出现冲突(conflict)
. 在这种情况,Git会停止rebase
并会让你去解决 冲突;在解决完冲突后,用"git-add"
命令去更新这些内容的索引(index)
, 然后,你无需执行 git-commit
,只要执行:
$ git rebase --continue
这样git会继续应用(apply)
余下的补丁。
在任何时候,你可以用--abort
参数来终止rebase
的行动,并且"mywork"
分支会回到rebase
开始前的状态。
$ git rebase --abort
如何多人协作开发
多人协作开发,就不能使用master
分支了,而是要每个开发者单独拉一个分支,使用git checkout -b <branchname>
,运行git branch
可以看到本地所有的分支名称。
自己的分支,如果想同步master
分支的内容,可运行git merge master
。切换分支可使用git checkout <branchname>
。
在自己的分支上修改了内容,可以将自己的分支提交到远程服务器
git checkout -b <branchname> //创建并切换分支
git add .
git commit -m "xxx"
git push origin <branchname>
最后,待代码测试没问题,再将自己分支的内容合并到master
分支,然后提交到远程服务器。
git checkout master //切换分支
git merge <branchname> //合并分支
git push origin master...
详细版
首先,我们创建dev
分支,然后切换到dev
分支:
$ 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 branch
* dev
master
git branch
命令会列出所有分支,当前分支前面会标一个*号。
然后,我们就可以在dev
分支上正常提交,比如对readme.txt
做个修改,加上一行:
Creating a new branch is quick.
然后提交:
$ git add readme.txt
$ git commit -m "branch test"
[dev b17d20e] branch test
1 file changed, 1 insertion(+)
现在,dev分支的工作完成,我们就可以切换回master分支:
$ git checkout master
Switched to branch 'master'
切换回master
分支后,再查看一个readme.txt
文件,刚才添加的内容不见了!因为那个提交是在dev分支上,而master
分支此刻的提交点并没有变.
现在,我们把dev
分支的工作成果合并到master
分支上:
$ git merge dev
Updating d46f35e..b17d20e
Fast-forward
readme.txt | 1 +
1 file changed, 1 insertion(+)
git merge命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就可以看到,和dev分支的最新提交是完全一样的。
注意到上面的Fast-forward
信息,Git
告诉我们,这次合并是“快进模式”,也就是直接把master
指向dev
的当前提交,所以合并速度非常快。
当然,也不是每次合并都能Fast-forward
,我们后面会讲其他方式的合并。
合并完成后,就可以放心地删除dev分支了:
$ git branch -d dev
Deleted branch dev (was b17d20e).
删除后,查看branch,就只剩下master分支了:
$ git branch
* master
因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全。
git
版本回退
- git reset –hard HEAD ^ ( ^ 表示回到上一个版本,回退几个版本后面就跟几个^,或
git reset –hard HEAD~3
,回退3个版本 ); git reset –hard 版本号
git
本地分支同步远程分支
远程先创建分支然后拉到本地维护
git checkout -b [本地分支名] origin/[远程分支名] //检出远程分支到本地一般设置一样的名字
本地先创建分支然后推送到远程
git checkout -b [本地分支名] //创建并切换到分支
git push origin [远程分支名]:[本地分支名] (--force 强制) //推送本地的分支(没有会自动创建)
git
重命名本地分支,并提交到远程
- 重命名
git branch -m oldBranchName newBranchName
- 删除远程分支:
git push origin oldBranchName
- 将重命名过的分支提交:
git push origin newBranchName
git
合并某个提交commit
到指定的分支上
把B
分支的commitInfo 提交 合并到 A
分支上
git checkout B
,来到B分支;git log
查找并记住commitInfo的提交id;git checkout A
切换到A分支;git cherry-pick commit_id
.
小结(实际使用直接看这里!!!)
Git鼓励大量使用分支:
查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>
创建+切换分支:git checkout -b <name>
合并某分支到当前分支:git merge <name>
删除分支:git branch -d <name>
(上一条报错时)强制删除分支:git branch -D <name>
绑定本地分支到远程服务器分支: git branch --set-upstream-to origin/[远程分支名] [本地分支名]
推送本地更新到远程分支: git push <远程库名>(origin) [本地分支名]:[远程分支名]
克隆远程分支:git clone -b [远程分支名] [远程仓库地址]
获取远程服务器的指定分支: git pull <远程库名>(origin) <远程分支名>:<本地分支名>
撤销上次提交(没有更新到远程仓库): git reset --soft HEAD^
撤销上次提交(已更新至远程仓库): git reset --hard HEAD^
拉取远程分支并在本地同步: git fetch origin [远程分支]:[本地分支名,没有会新建]
在本地创建分支xxx(fetch的远程分支)并切换到该分支: git checkout -b dev(本地分支名称) origin/dev(远程分支名称)
暂存更改: git stash
恢复暂存更改: git stash pop
(本地)分支重命名:git branch -m old_branch_name new_branch_name
修改最新一条提交信息: git commit --amend
(进入编辑模式修改)
添加标签信息:git tag -a(表示添加注释) tagname -m"注释内容"
为历史提交添加版本: git tag -a tagname commitId -m"注释内容"
显示标签列表: git tag -l(列表显示)-n(显示注释)
显示标签详情:git show tagname
推送标签:git push origin tagname
推送所有标签:git push origin --tags
删除标签:git tag -d tagname
删除远程标签:git push origin :refs/tags/{tagname}
git commit规范
# 主要type
feat: 增加新功能
fix: 修复bug
# 特殊type
docs: 只改动了文档相关的内容
style: 不影响代码含义的改动,例如去掉空格、改变缩进、增删分号
build: 构造工具的或者外部依赖的改动,例如webpack,npm
refactor: 代码重构时使用
revert: 执行git revert打印的message
# 暂不使用type
test: 添加测试或者修改现有测试
perf: 提高性能的改动
ci: 与CI(持续集成服务)有关的改动
chore: 不修改src或者test的其余修改,例如构建过程或辅助工具的变动
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。