因为工作需要,整理了一个关于Git使用的ppt,这里同步记录一下。
1. 什么是Git
Git,全称是分布式版本控制系统,Git通常在编程中会用到,并且Git支持分布式部署,可以有效、高速的处理从很小到非常大的项目版本管理。分布式相比于集中式的最大区别在于开发者可以提交到本地,每个开发者通过克隆(git clone),在本地机器上拷贝一个完整的Git仓库。
当你在本地写好某一个编程文档时,发现有些地方需要修改或者删除,有的人可能会直接在当前文件中直接修改,有的人会复制一份在上面修改,然后删除没用的文件。但是当你发现还是原来的文件好或者另外的版本好时,就可能手足无措了。
此时使用git工具,我们可以在本地建一个版本库,每当我们需要修改时,就可以把之前的版本提交并标明此版的特点。这样文件夹里就只有一个编程文档了。当你需要哪个版本时,只要在版本库中恢复一下就可以了。
为什么需要版本控制
版本库又名仓库(repository),可以简单理解成一个目录(存放好多版本的目录),目录里所有文件都被Git管理起来,每个文件的修改,删除,Git都会跟踪,以便任何时候都可以追踪历史或者在将来某一时刻可以还原修改。
Git和SVN都是程序员用来管理代码的,在企业中进行开发,一个人负责一个项目的情况几乎不可能,从需求评审,UI设计,前端开发,后台开发,测试,整个过程都是需要团队来配合的。这个时候,版本控制都显得尤为重要。
Git的功能特性
从一般开发者的角度来看,Git有以下功能:
1、从服务器上克隆完整的Git仓库(包括代码和版本信息)到单机上。
2、在自己的机器上根据不同的开发目的,创建分支,修改代码。
3、在单机上自己创建的分支上提交代码。
4、在单机上合并分支。
5、把服务器上最新版的代码fetch下来,然后跟自己的主分支合并。
6、生成补丁(patch),把补丁发送给主开发者。
7、看主开发者的反馈,如果主开发者发现两个一般开发者之间有冲突(他们之间可以合作解决的冲突),就会要求他们先解决冲突,然后再由其中一个人提交。如果主开发者可以自己解决,或者没有冲突,就通过。
8、一般开发者之间解决冲突的方法,开发者之间可以使用pull 命令解决冲突,解决完冲突之后再向主开发者提交补丁。
从主开发者的角度(假设主开发者不用开发代码)看,git有以下功能:
1、查看邮件或者通过其它方式查看一般开发者的提交状态。
2、打上补丁,解决冲突(可以自己解决,也可以要求开发者之间解决以后再重新提交,如果是开源项目,还要决定哪些补丁有用,哪些不用)。
3、向公共服务器提交结果,然后通知所有开发人员。
Git工作流程
Git的一般工作流程如下:
- 克隆 Git 资源作为工作目录。
- 在克隆的资源上添加或修改文件。
- 如果其他人修改了,你可以更新资源。
- 在提交前查看修改。
- 提交修改。
- 在修改完成后,如果发现错误,可以撤回提交并再次修改并提交。
Git工作区、暂存区和版本库
工作区:就是你在电脑里能看到的目录。
暂存区:英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
版本库:工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。
图中左侧为工作区,右侧为版本库。在版本库中标记为 “index” 的区域是暂存区(stage/index),标记为 “master” 的是 master 分支所代表的目录树。
图中我们可以看出此时 “HEAD” 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。
图中的 objects 标识的区域为 Git 的对象库,实际位于 “.git/objects” 目录下,里面包含了创建的各种对象及内容。
当对工作区修改(或新增)的文件执行 git add 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。
当执行 git reset HEAD 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
当执行 git rm --cached 命令时,会直接从暂存区删除文件,工作区则不做出改变。
当执行 git checkout . 或者 git checkout – 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区中的改动。
当执行 git checkout HEAD . 或者 git checkout HEAD 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
2. Git与SVN的区别
Git是分布式的,SVN是集中式的。
这是 Git 和 SVN 最大的区别。若能掌握这个概念,两者区别基本搞懂大半。因为 Git 是分布式的,所以 Git 支持离线工作,在本地可以进行很多操作,包括接下来将要重磅推出的分支功能。而 SVN 必须联网才能正常工作。
Git复杂概念多,SVN简单易上手
所有同时掌握 Git 和 SVN 的开发者都必须承认,Git 的命令实在太多了,日常工作需要掌握add,commit,status,fetch,push,rebase等,若要熟练掌握,还必须掌握rebase和merge的区别,fetch和pull的区别等,除此之外,还有cherry-pick,submodule,stash等功能,仅是这些名词听着都很绕。
在易用性这方面,SVN 会好得多,简单易上手,对新手很友好。但是从另外一方面看,Git 命令多意味着功能多,若我们能掌握大部分 Git 的功能,体会到其中的奥妙,会发现再也回不去 SVN 的时代了。
Git分支廉价,SVN分支昂贵
在版本管理里,分支是很常使用的功能。在发布版本前,需要发布分支,进行大需求开发,需要 feature 分支,大团队还会有开发分支,稳定分支等。在大团队开发过程中,常常存在创建分支,切换分支的需求。
Git 分支是指针指向某次提交,而 SVN 分支是拷贝的目录。这个特性使 Git 的分支切换非常迅速,且创建成本非常低。
而且 Git 有本地分支,SVN 无本地分支。在实际开发过程中,经常会遇到有些代码没写完,但是需紧急处理其他问题,若我们使用 Git,便可以创建本地分支存储没写完的代码,待问题处理完后,再回到本地分支继续完成代码。
3. Git的使用方法
Git 下载地址点这里,。
安装好后鼠标右键选择Git Bash Here启动Git命令行界面,后面讲到的所有指令都将在Git Bash中运行。
Git相关配置
输入以下指令对Git进行配置(不需要输入“$”):
Git 是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址
git config 命令的 --global 参数,用了这个参数,表示你这台机器上所有的 Git 仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址(不加 --global)。
可以使用 git config --list 检查已有的配置信息。
Git相关命令
初始化本地仓库
其中:
cd 改变目录
mkdir 创建目录
pwd 用于显示当前目录
git init 把当前目录初始化为 git 仓库
ls -ah 查看当前目录下的文件,包含隐藏文件 (不带 -ah 看不了隐藏文件)
HEAD 文件中的内容其实只是包含了一个索引信息,并且,这个索引将总是指向你的项目中的当前开发分支。
objects 子目录,它包含了你的项目中的所有对象,我们不必直接地了解到这些对象内容,我们应该关心是存放在这些对象中的项目的数据。
refs 子目录,它用来保存指向对象的索引。
Git 基本操作
Git 的工作就是创建和保存你项目的快照及与之后的快照进行对比。
Git 常用的是以下 6 个命令:git clone、git push、git add 、git commit、git checkout、git pull。
workspace:工作区
staging area:暂存区/缓存区
local repository:版本库或本地仓库
remote repository:远程仓库
添加仓库文件
当前目录有未添加到仓库的文件时,查看仓库目前状态,会在文件前显示??
新项目中,添加所有文件很普遍,我们可以使用 git add . 命令来添加当前项目的所有文件。
修改README文件后再次查看
AM
状态的意思是这个文件在我们将它添加到缓存之后又有改动。改动后我们再执行git add .
命令将其添加到缓存中。
查看修改内容,查看文件不同
git diff # 查看工作区(work dict)和暂存区(stage)的区别
git diff --cached # 查看暂存区(stage)和分支(master)的区别
git diff HEAD -- <file> # 查看工作区和版本库里面最新版本的区别
如: git diff readme.txt 表示查看 readme.txt 修改了什么,有什么不同
添加仓库文件
git add <file> # 添加文件到仓库
git commit -m "description" # 提交该文件到仓库, description 为对该次提交的描述说明
git status # 查看仓库目前状态 (项目是否有修改、添加、未追踪的文件等)
Git 回退版本
git reset # 用于回退版本,可以指定退回某一次提交的版本。格式如下:
git reset [--soft | --mixed | --hard] [HEAD]
# --mixed 为默认,可以不用带该参数,用于重置暂存区的文件与上一次的提交(commit)保持一致,
# 工作区文件内容保持不变。
例如:
$ git reset HEAD^ # 回退所有内容到上一个版本
$ git reset HEAD^ hello.php # 回退 hello.php 文件的版本到上一个版本
其余参数:
–soft 参数用于回退到某个版本:
实例:
$ git reset --soft HEAD~3 # 回退上上上一个版本
–hard 参数撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到上一次版本,并删除之前的所有信息提交:
实例:
$ git reset –hard HEAD~3 # 回退上上上一个版本
$ git reset –hard bae128 # 回退到某个版本回退点之前的所有信息。
$ git reset --hard origin/master # 将本地的状态回退到和远程的一样
注意:谨慎使用 –hard 参数,它会删除回退点之前的所有信息。
HEAD 说明:
HEAD 表示当前版本
HEAD^ 上一个版本
HEAD^^ 上上一个版本
HEAD^^^ 上上上一个版本
以此类推…可以使用 ~数字表示
HEAD~0 表示当前版本
HEAD~1 上一个版本
HEAD^2 上上一个版本
HEAD^3 上上上一个版本
以此类推…
git reset HEAD 命令用于取消已缓存的内容。现在两个文件修改后,都提交到了缓存区:
我们现在要取消其中一个的缓存,指令:
$ git reset HEAD README
之后再执行 git commit,只会将 test1.c 文件的改动提交,而 README 没有。
可以看到 README 文件的修改并未提交。
这时我们可以使用以下命令将 hello.php 的修改提交:
删除工作区文件
git rm 命令用于删除文件。
git rm 删除文件有以下几种形式:
1.将文件从暂存区和工作区中删除:
$ git rm <file>
2. 如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f。
3. 如果想把文件从暂存区域移除,但仍然希望保留在当前工作目录中,换句话说,仅是从跟踪清单中删除,使用 --cached 选项即可:
移动或重命名工作区文件
git mv 命令用于移动或重命名一个文件、目录或软连接。
$ git mv [file] [newfile]
如果新但文件名已经存在,但还是要重命名它,可以使用 -f 参数:
$ git mv -f [file] [newfile]
我们可以添加一个 README 文件(如果没有的话),然后对其重命名:
管理分支
几乎每一种版本控制系统都以某种形式支持分支。使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。分支指令如下:
$ git branch # 列出所有本地分支
$ git branch -a # 列出所有本地分支和远程分支
$ git branch [branch-name] # 新建一个分支,但依然停留在当前分支
$ git checkout -b [new_branch] [remote-branch] # 新建一个分支,并切换到该分支
$ git checkout [branch-name] # 切换到指定分支,并更新工作区
$ git merge [branch] # 合并指定分支到当前分支
$ git cherry-pick [commit] # 选择一个 commit,合并进当前分支
$ git branch -d [branch-name] # 删除本地分支,-D 参数强制删除分支
$ git push [remote] :[remote-branch] # 删除远程分支
如果我们要手动创建一个分支。执行 git branch (branchname) 即可。现在我们可以看到,有了一个新分支 testing。
当你以此方式在上次提交更新之后创建了新分支,如果后来又有更新提交, 然后又切换到了 testing 分支,Git 将还原你的工作目录到你创建分支时候的样子。
当我们切换到 testing 分支的时候,我们添加的新文件 branchTest.h 被移除了。
我们也可以使用 git checkout -b (branchname)
命令来创建新分支并立即切换到该分支下,从而在该分支中操作。
在下面的例子中,我们创建了一个分支,在该分支的上移除了一些文件 test1.c,并添加了 test4.c 文件,然后切换回我们的主分支,删除的 test1.c 文件又回来了,且新增加的 test4.c 不存在主分支中。
使用分支将工作切分开来,从而让我们能够在不同开发环境中做事,并来回切换。
删除分支命令:
$ git branch -d (branchname)
例如我们要删除 testing 分支:
一旦某分支有了独立内容,你终究会希望将它合并回到你的主分支。 你可以使用 $ git merge 命令将任何分支合并到当前分支中去:
以上实例中我们将 newtest 分支合并到主分支去,test1.c 文件被删除。
合并完后就可以删除分支 newtest 。
合并并不仅仅是简单的文件添加、移除的操作,Git 也会合并修改。
首先,我们创建一个叫做 change_site 的分支,切换过去,修改 test1.c 中的内容并提交。
现在,假如切换回 master 分支我们可以看内容恢复到我们修改前的(空文件,没有代码),我们再次修改 test1.c 文件。现在这些改变已经记录到我的 “master” 分支了。接下来我们将 “change_site” 分支合并过来。
我们将前一个分支合并到 master 分支,一个合并冲突就出现了,接下来我们需要手动去修改它。
通过vim修改master分支上test1.c的内容,在 Git 中,我们可以用 git add 要告诉 Git 文件冲突已经解决
现在我们成功解决了合并中的冲突,并提交了结果。提交了结果。
Git vim使用详解点这里。
Git 标签
如果项目达到一个重要的阶段,并希望永远记住那个特别的提交快照,可以使用 git tag 给它打上标签。
比如说,我们想为我们的 learngit 项目发布一个"1.0"版本。 我们可以用
命令给最新一次提交打上(HEAD)“v1.0"的标签。其中 -a 选项意为"创建一个带注解的标签”。 不用 -a 选项也可以执行的,但它不会记录这标签是啥时候打的,谁打的,也不会让你添加个标签的注解。
当你执行 git tag -a 命令时,Git 会打开你的编辑器,让你写一句标签注解,就像你给提交写注解一样。
现在,注意当我们执行 git log --decorate 时,我们可以看到我们的标签了:
如果我们忘了给某个提交打标签,又将它发布了,我们可以给它追加标签。
例如,假设我们发布了提交 7d816f0 ,但是那时候忘了给它打标签。 我们现在也可以:
如果我们要查看所有标签可以使用以下命令:
Git 远程仓库(Github)
Git 并不像 SVN 那样有个中心服务器。
目前我们使用到的 Git 命令都是在本地执行,如果你想通过 Git 分享你的代码或者与其他开发人员合作。 你就需要将数据放到一台其他开发人员能够连接的服务器上。
这里,我们使用了 Github 作为远程仓库。
从远程仓库克隆
我们使用 git clone 从现有 Git 仓库中拷贝项目(类似 svn checkout)。
克隆仓库的命令格式为:git clone <repo> <directory>
其中repo表示Git 仓库,directory代表本地目录,比如,要克隆 Ruby 语言的 Git 代码仓库 Grit,可以用下面的命令:
git clone git://github.com/schacon/grit.git mygrit
添加远程库
以 Github 为例作为远程仓库。由于本地 Git 仓库和 GitHub 仓库之间的传输是通过SSH加密的,所以我们需要配置验证信息,使用以下命令生成 SSH Key:
$ ssh-keygen -t rsa -C "youremail@example.com"
后面的 your_email@youremail.com 改为你在 Github 上注册的邮箱,之后会要求确认路径和输入密码,我们这使用默认的一路回车就行。
成功的话会在 ~/ 下生成 .ssh 文件夹,进去,打开 id_rsa.pub,复制里面的 key。
回到 github 上,进入 Account=>Setting=>SSH and GPG keys=>New SSH key,在key处填入 id_rsa.pub 中的内容,新建SSH key,成功结果如图:
为了验证是否成功,输入以下命令:$ ssh -T git@github.com
,结果如图:
之后登录后点击" New repository " 如下图所示:之后在在Repository name 填入 runoob-git-test(远程仓库名) ,其他保持默认设置,点击"Create repository"按钮,就成功地创建了一个新的Git仓库:以上信息告诉我们可以从这个仓库克隆出新的仓库,也可以把本地仓库的内容推送到GitHub仓库。
现在,我们根据 GitHub 的提示,在本地的仓库下运行命令(方框中内容为用户名/远程仓库名):
然后输入$ git push -u origin master
,现在刷新github,就可以看到我们提交的内容了。
提取远程仓库
查看当前的远程库:
$ git remote # 查看当前配置有哪些远程仓库
$ git remote -v # 查看每个别名的实际链接地址
提取远程仓库:
$ git fetch # 从远程仓库下载新分支与数据:
$ git merge # 从远端仓库提取数据并尝试合并到当前分支
假设你配置好了一个远程仓库,并且你想要提取更新的数据,你可以首先执行git fetch [alias]
告诉 Git 去获取它有你没有的数据,然后你可以执行 git merge [alias]/[branch]
以将服务器上的任何更新(假设有人这时候推送到服务器了)合并到你的当前分支。
在github上修改其中一个文件,提交后,在Git中输入$ git fetch origin
,结果如图:
方框中的信息
8e510f3…4ae2b8b master -> origin/master
说明 master 分支已被更新,我们可以使用以下命令$ git merge origin/master
将更新同步到本地:
查看本地文件,发现test2.c已经被修改。
推送到远程仓库
推送你的新分支与数据到某个远端仓库命令:$ git push [alias] [branch]
以上命令将你的 [branch] 分支推送成为 [alias] 远程仓库上的 [branch] 分支,实例如下:
重新回到我们的 Github 仓库,可以看到文件已经提交上来了。
删除远程仓库
删除远程仓库你可以使用命令:$ git remote rm [别名]
具体实例如下:
参考资料
Git学习资料:
https://git-scm.com/book/en/v2
https://www.runoob.com/git/git-tutorial.html
github提高国内访问速度:https://blog.csdn.net/weixin_46408092/article/details/108813355