【Git】

一、git介绍

git - 分布式版本控制工具Version control systems(VCSs) VS 集中式版本控制工具

Git 是一个免费的、开源的分布式版本控制系统,可以快速高效地处理从小型到大型的各种项目。

Git 易于学习,占地面积小,性能极快。它具有廉价的本地库(在本地磁盘上),方便的暂存区域和多个工作流分支等特性。其性能优于Subversion、CVS、Perforce和ClearCase 等版本控制工具。

1.1、何为版本控制

版本控制是一种记录文件内容变化,以便将来查阅特定版本修订情况的系统。

版本控制其实最重要的是可以记录文件修改历史记录,从而让用户能够查看历史版本,方便版本切换。

1.2、为什么需要版本控制

从个人开发过渡到团队协作。

1.3、版本控制工具

①集中式版本控制工具

        CVS、SVN(Subversion)、vss......
        集中化的版本控制系统诸如CVS、SVN 等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。多年以来,这已成为版本控制系统的标准做法。
        这种做法带来了许多好处,每个人都可以在一定程度上看到项目中的其他人正在做些什么。而管理员也可以轻松掌控每个开发者的权限,并且管理一个集中化的版本控制系统,要远比在各个客户端上维护本地数据库来得轻松容易。
        事分两面,有好有坏。这么做显而易见的缺点是中央服务器的单点故障。如果服务器宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。

②分布式版本控制工具

        Git、Mercurial、Bazaar、Darcs......
        像 Git 这种分布式版本控制工具,客户端提取的不是最新版本的文件快照,而是把代码仓库完整地镜像下来(本地库)。这样任何一处协同工作用的文件发生故障,事后都可以用其他客户端的本地仓库进行恢复。因为每个客户端的每一次文件提取操作,实际上都是一次对整个文件仓库的完整备份。
        分布式的版本控制系统出现之后,解决了集中式版本控制系统的缺陷:
        1.服务器断网的情况下也可以进行开发(因为版本控制是在本地进行的)
        2.每个客户端保存的也都是整个完整的项目(包含历史记录,更加安全)

1.4、Git简史

很多人都知道,Linus在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了。

Linus虽然创建了Linux,但Linux的壮大是靠全世界热心的志愿者参与的,这么多人在世界各地为Linux编写代码,那Linux的代码是如何管理的呢?

事实是,在2002年以前,世界各地的志愿者把源代码文件通过diff的方式发给Linus,然后由Linus本人通过手工方式合并代码!

你也许会想,为什么Linus不把Linux代码放到版本控制系统里呢?不是有CVS、SVN这些免费的版本控制系统吗?因为Linus坚定地反对CVS和SVN,这些集中式的版本控制系统不但速度慢,而且必须联网才能使用。有一些商用的版本控制系统,虽然比CVS、SVN好用,但那是付费的,和Linux的开源精神不符。

不过,到了2002年,Linux系统已经发展了十年了,代码库之大让Linus很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是Linus选择了一个商业的版本控制系统BitKeeper,BitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这个版本控制系统。

安定团结的大好局面在2005年就被打破了,原因是Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。开发Samba的Andrew试图破解BitKeeper的协议(这么干的其实也不只他一个),被BitMover公司发现了(监控工作做得不错!),于是BitMover公司怒了,要收回Linux社区的免费使用权。

Linus可以向BitMover公司道个歉,保证以后严格管教弟兄们,嗯,这是不可能的。实际情况是这样的:

Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux系统的源码已经由Git管理了!牛是怎么定义的呢?大家可以体会一下。

Git迅速成为最流行的分布式版本控制系统,尤其是2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。

历史就是这么偶然,如果不是当年BitMover公司威胁Linux社区,可能现在我们就没有免费而超级好用的Git了。

1.5、Git工作机制

我们将代码写入工作区,而工作区并不是指我们写代码的环境集成软件(IDE),是我们代码存放的磁盘的目录位置。工作区 --(git add)-> 暂存区,我么可以将工作区的代码临时存储到暂存区。暂存区 --(git commit)-> 本地库,将暂存区的代码提交到本地库,同时就可以生成历史版本,一旦生成历史版本,我们提交的代码就无法删除了。为什么无法删除呢?因为我们新版本是基于上一版本的,所以我们不能单独删除上一版本的代码。

代码托管中心是基于网络服务器的远程仓库代码,一般我们简单称为远程库。所以在上诉操作中,我们还可以将本地库的代码推送到远程库上(push)。

二、Git常用命令

2.1、设置用户签名

我们下载完Git后,在桌面点击右键,之后点击Git Bash Here。

我们在命令行中输入上表中前两行命令,姓名可以自己起,邮箱可以是虚拟的也可以是真实的。

我们如何查看自己的用户签名是否设置成功呢?

Git首次安装必须设置用户签名,否则无法提交代码!

说明:签名的作用是区分不同操作者身份。用户的签名信息在每一个版本的提交信息中能够看到,以此确认本次提交是谁做的。

※注意:这里设置用户签名(仅仅代表了Windows下的本地的Git客户端)和将来登录GitHub(或其他代码托管中心)的账号没有任何关系。 .

2.2、初始化本地库

①在自己的磁盘上创建一个名为Git-Space的文件夹,再在其中创建一个project1代表你要写的项目。

②我们可以在此文件夹中的空白区域直接右键进入当前项目所在的路径。

③键入命令"git init"

"ll":查看文件。

"ll -a":查看隐藏文件。

④查看本地库状态

⑤新增文件并查看状态

2.3、添加暂存区

再次查看本地库状态

如果我们不想要文件保存在暂存区上,我们可以使用上面它给的命令删除,但是它只是将文件从暂存区中删除,工作区中还是保留的。

再次查看状态,绿色又变成了红色。

"git add"的交互式版本:假如我们修改了hello.txt,一个是我们正式的代码,一个是用来debug的无用代码,但我不想再下次提交快照时提交这个debug代码。

我们可以手动删除不想要的代码,再进行"git add":"git add -p":它允许我交互式的暂存文件的片段,它可以弹出一个界面来指定片段。

"git diff -cached":显示暂存区里的更改,上述操作后它将只显示我想要保留的实际更改。

2.4、提交本地库

git commit -m "日志信息" 文件名

查看本地库状态

"git reflog":查看版本信息,查看引用日志信息。

"git log":查看详细日志的命令。

"git checkout":可以在历史记录之间移动,我们可以给checkout之前版本commit后的一个哈希值且不需要输入整个哈希值,它就可以知道是哪一次提交。这将改变我的当前工作目录的状态到我刚刚指定的那个提交。

我们还可以输入分支名来返回或者进入我们想要的分支中。

"git checkout"也会改变你当前工作目录的内容,如果我们修改了当前目录下的hello.txt文件

这时再运行命令会提示我们有一个文件已经被修改

我们可以用"git checkout -f"去强制执行,但是这样它就会丢弃我刚刚的更改。

"git checkout"移动了HEAD指针,然后还根据HEAD指针改变了当前工作目录的内容。 

"git checkout -b dog": 这个命令的作用就是,创建新分支并切换到该分支。

"git diff":可以显示当前目录自上次快照以来发生了什么变化。"git diff"还可以传入参数,例如你可以进行"git diff 85727ca hello.txt",看看现在的"hello.txt"相对于"85727ca"时的差异。

如果hello.txt前面没有参数,那么它计算的是hello.txt和HEAD之间的差异。

我可以比较从"85727ca"到HEAD之间,"hello.txt"有什么变化。

2.5、修改文件

我们想要修改之前提交上去的代码,那么修改完成后在"git status"查看一下本地库文件当前状态,这里红字提示我们文件被修改了。红色则说明这次的修改并没有被添加到暂存区。 

当我们将文件添加到暂存区后,再次查看状态

git是按照行来维护文件的,如果我们修改了一行,它没有办法表示出来,那么它只能将我们修改的这一行之前的删除,然后再把修改之后的内一行内容新增进来。

这时我们再查看状态和版本信息就会发现,已经提交且有两个版本了。

指针指向哪一个版本则就会使用哪一个。

2.6、版本穿梭

"git reset --hard 版本号" 

我们还可以将其更改回最新版本再查看。查看hello.txt也是同理。

git切换版本,底层是移动HEAD指针。

2.7、基础 

  • git help <command>: 获取 git 命令的帮助信息
  • git init: 创建一个新的 git 仓库,其数据会存放在一个名为 .git 的目录下
  • git status: 显示当前的仓库状态
  • git add <filename>: 添加文件到暂存区
  • git commit: 创建一个新的提交
  • git log: 显示历史日志
  • git log --all --graph --decorate: 可视化历史记录(有向无环图)
  • git diff <filename>: 显示与暂存区文件的差异
  • git diff <revision> <filename>: 显示某个文件两个版本之间的差异
  • git checkout <revision>: 更新 HEAD 和目前的分支

2.8、分支和合并

  • git branch: 显示分支
  • git branch <name>: 创建分支
  • git checkout -b <name>: 创建分支并切换到该分支
    • 相当于 git branch <name>; git checkout <name>
  • git merge <revision>: 合并到当前分支
  • git mergetool: 使用工具来处理合并冲突
  • git rebase: 将一系列补丁变基(rebase)为新的基线

2.9、远端操作

  • git remote: 列出远端
  • git remote add <name> <url>: 添加一个远端
  • git push <remote> <local branch>:<remote branch>: 将对象传送至远端并更新远端引用
  • git branch --set-upstream-to=<remote>/<remote branch>: 创建本地和远端分支的关联关系
  • git fetch: 从远端获取对象/索引
  • git pull: 相当于 git fetch; git merge
  • git clone: 从远端下载仓库

2.10、撤销

  • git commit --amend: 编辑提交的内容或信息
  • git reset HEAD <file>: 恢复暂存的文件
  • git checkout -- <file>: 丢弃修改
  • git restore: git2.32版本后取代git reset 进行许多撤销操作

2.11、Git 高级操作 

  • git config: Git 是一个 高度可定制的 工具
  • git clone --depth=1: 浅克隆(shallow clone),不包括完整的版本历史信息
  • git add -p: 交互式暂存
  • git rebase -i: 交互式变基
  • git blame: 查看最后修改某行的人
  • git stash: 暂时移除工作目录下的修改内容,它并不是被删除了而是暂存在某个地方。"git stash pop":将重新展示这个更改。
  • git bisect: 通过二分查找搜索历史记录
  • .gitignore指定 故意不追踪的文件

三、Git分支操作

在版本控制过程中,同时推进多个任务,为每个任务,我们就可以创建每个任务的单独分支。使用分支意味着程序员可以把自己的工作从开发主线上分离开来,开发自己分支的时候,不会影响主线分支的运行。分支可以简单理解为副本,一个分支就是一个单独的副本。(分支底层其实也是指针的引用)

分支的好处:同时并行推进多个功能开发,提高开发效率。各个分支在开发过程中,如果某一个分支开发失败,不会对其他分支有任何影响。失败的分支删除重新开始即可。

3.1、分支的操作

"git branch --set-upstream-to=":知道本地分支对应的远程分支,这样"git push"命令就可以简化输入了,它会自动扩展所有的参数。

"branch -vv":这会详细地告诉我所有分支的信息。 

3.2、切换分支

我们在"hot-fix"的分支上修改"hello.txt"代码,之后查看本地库状态。

修改后,进行添加和提交。

3.3、合并分支

我们想将热修"hot-fix"分支合并到"master"上,我们先要站在"master"分支上才可合并。

冲突产生的原因:合并分支时,两个分支在同一个文件的同一个位置有两套完全不同的修改。Git 无法替我们决定使用哪一个。必须人为决定新代码内容。

"git merge --abort":这将回到我"git merge"之前的状态

"git merge --continue":来告诉git我们已经解决了合并冲突。

我们先在"master"分支下进行修改后添加和提交。

我们同时切换分支到"hot-fix"并且同样将文件修改后进行添加和提交。

此时,我们将分支转换回"master",并且在此分支上合并"hot-fix"分支,此时发生了代码冲突

我们可以手动打开文件,在代码冲突处已经标识出冲突。

而解决的方法则是删除多余即可。

保存文件后,不要忘了将认为修改的代码添加到暂存区,且提交本地库,但是此时提交不可以带文件名

合并分支只会修改"master"分支,不会修改"hot-fix"分支。

master、hot-fix其实都是指向具体版本记录的指针。当前所在的分支,其实是由HEAD决定的。所以创建分支的本质就是多创建一个指针。

HEAD如果指向master,那么我们现在就在master分支上。

HEAD 如果执行hot-fix,那么我们现在就在hot-fix分支上。

所以切换分支的本质就是移动HEAD指针。

"git mergetool":启动vimdiff程序,这是出现合并冲突时使用的工具。 

四、Github操作

4.1、创建远程仓库

4.2、远程仓库操作

"git fetch":用于检索在远程仓库上的更改,并在本地上获取这些更改。一旦检索到更改,你可以使用"git merge"将本地分支更新到与远程分支指向相同位置。

4.2.1、创建远程仓库别名

链接太长记不住,故给链接创建别名!

4.2.2、推送本地分支到远程仓库

在推送分支时会遇到一个错误:fatal: unable to access 'https://github.com/Ailichenghuan/project1.git/': SSL certificate problem: unable to get local issuer certificate.

这个问题是由于没有配置信任的服务器HTTPS验证。默认,cURL被设为不信任任何CAs,就是说,它不信任任何服务器验证。只需要执行下面命令就可以解决:

git config --global http.sslVerify false

我们可以选择第一个,选择一个你的浏览器的一个账号。

4.2.3、拉取远程库到本地库 

如果我们在远程修改了"hello.txt"代码,并且将这次改变提交。 

这时我们就可以在命令行拉取被修改后的远程库内容了。

4.2.4、克隆远程库到本地 

我们新建一个文件夹"Git-Clone"代表我们要克隆远程库的内容到此文件夹。 

之后再次文件夹下"Git Bash Here"

我们想要克隆代码,就要先拿到代码的链接。

但是在克隆前,我们要先打开Windows的凭据管理器,把之前账号的凭据管理器删除,因为Windows只能同时记住一个账号。

克隆代码并不需要登陆账号,因为创建的是公共库,是没有权限的,任何人都能克隆。 

clone会做如下操作:1、拉取代码。2、初始化本地仓库。3、创建别名(自动别名origin)。

当你想要使用"git clone"来克隆一个超大的仓库时,默认情况下,"git clone"会复制远程仓库的整个版本历史记录,但是你可以用"--shallow",这将不会克隆整个版本记录。

4.2.5、团队内协作

如果团队内有另外的人也想要修改我们本人创建的库,那么需要将此人拉入自己的团伙,不然会提示GitHub没有权限修改库中的内容,无法推送。

我们需要在setting中找到Manage access

在邀请完后,我们会看到被邀请者后面有一个Pending Invite邀请函,我们需要将它复制下来,发给被邀请人,被邀请人受到地址后,通过登陆自己的GitHub在搜索框输入邀请函,然后我们就可以看到自己被邀请,可以选择接受或拒绝。

4.2.6、跨团队协作

因为是跨团队协作,所以项目拥有者需要复制自己项目的链接发送给修改者,发送后修改者需要将此项目叉一份到本地来。 

如果团队外的人修改代码结束,想要让团队内的人看到修改,那么我们需要拉取请求。

提交后,团队内的人可以在自己的拉取请求中看到。

如果修改的代码是自己需要的,我们可以点击Merge pull request提交合并申请,把修改的代码合并到咱们自己的分支代码中。

4.2.7、SSH免密登录

我们可以看到远程仓库中还有一个 SSH 的地址,因此我们也可以使用 SSH 进行访问。

在Windows的C盘目录下找到自己用户名的文件夹:

如果之前有.ssh文件夹就先将其删除,之后点击右键,在此目录下Git Bash Here。

"ssh-keygen -t rsa -C 3418956299@qq.com":我们键入这个命令可以生成.ssh密钥目录,"ssh-keygen":生成ssh免密登陆协议的命令,"-t":代表使用什么加密方法,"rsa":非对称加密协议,"-C":代表描述,把下面账号的邮箱写入是说明我们当前的免密登陆协议是专门针对这个账号分配的。

输入后连续敲三次回车,什么都不用输入:

我们查看一下公钥并将其复制下来:

将其复制到我们自己的账号/别人的账号下:

随便起一个名字后将我们的密钥复制过来:

五、IDEA集成Git

5.1、配置Git忽略文件 

为什么要忽略它们:与项目的实际功能无关,不参与服务器上部署运行。把它们忽略掉能够屏蔽 IDE 工具之间的差异。

怎么忽略:①创建忽略规则文件xxxx.ignore(前缀名随便起,建议是 git.ignore)

②这个文件的存放位置原则上在哪里都可以,为了便于让~/.gitconfig 文件引用,建议也放在用户家目录下。

git.ignore文件模版内容如下:

# Compiled class file
*.class

# Log file

*.log

# BlueJ files

*.ctxt

# Mobile Tools for Java (J2ME)

.mtj.tmp/

# Package Files #

*.jar
*.war
*.nar
*.ear

*.zib

# virtual machine crash logs, see http://ww,java.com/en/download/help/error hotspot.xml

hs_err_pid*

.classpath

.project

.settings

target

.idea

*.iml

创建完git.ignore文件后还要再.gitconfig里引用下此文件。 

注意:这里要使用“正斜线(/)”,不要使用“反斜线(\)”

5.2、定位Git程序 

 

5.3、初始化本地库

我们可以通过上述右键的方式打开此项目的家目录,我们发现在目录下并没有".git"的配置文件。我们可以看到目录文件均变红了,这就代表git已经检测到了这个文件,但是文件还没有被添加到暂存区。

我们可以对".xml"右键直接选择上图所示的步骤来添加。

我们看到图标颜色变绿了,那么就代表添加成功。如果一个项目中肯定是有多个文件的,我们可以直接在项目点击右键,同样的方式提交,提交后我们看到忽略文件没有被提交,它们还是红色的。

添加后,我们可以同样右键找到commit,出现下图所示的情况等待提交成功。 

此时它们又变回了最原始的颜色。

5.4、切换版本 

我们在主函数上随便改动一下代码,就发现被修改的文件改变了颜色。

我们依旧进行上述讲过的添加暂存区和提交本地库的步骤。

我们想要查看以前提交过的版本该怎么办呢?

如果我们要切换版本,那么直接在想要切换的版本上右键,点击下图蓝色的选项即可。 

5.5、创建分支 

或者我们直接点击IDEA的右下角,显示的是代表你当前在哪个分支。

我们创建一个"hot-fix"分支 

我们可以看到右下角是新创建的分支了,如果想切换回"master"分支那么点击即可。

5.6、合并分支 

我们在分支上修改代码并提交。

可是主分支并没有对这次修改代码的信息,那么我们需要将二者进行合并。

我们现在看到代码已经合并成功了。 

上图是我们在"hot-fix"分支下,在红圈处新加一行代码并提交。 

接着我们切换回"master"分支发现此处并没有代码。

我们在"master"分支上的同样位置写一份代码并提交。

在日志中我们就可以看到明显的出现了分支冲突。

此时点击合并就会出现冲突。

我们需要点击右侧的"merge"来手动合并代码(左侧代表"master"分支代码/右侧代表"hot-fix"分支代码/中间代表原始代码即未产生冲突前的代码)。

六、IDEA集成Github

我们还可以用Token口令来在IDEA上登录GitHub,在Github上点开settings。

6.1、分享项目到GitHub

6.2、推送代码到远程库

我们对代码进行了一些修改,并将其提交。

6.3、拉取远程库代码合并本地库

我们在GitHub上手动添加上一段代码

注意:push是将本地库代码推送到远程库,如果本地库代码跟远程库代码版本不一致,push的操作是会被拒绝的。也就是说,要想push成功,一定要保证本地库的版本要比远程库的版本高!因此一个成熟的程序员在动手改本地代码之前,一定会先检査下远程库跟本地代码的区别!如果本地的代码版本已经落后,切记要先 pu 拉取一下远程库的代码,将本地代码更新到最新以后,然后再修改,提交,推送!

注意:pull是拉取远端仓库代码到本地,如果远程库代码和本地库代码不一致,会自动合并,如果自动合并失败,还会涉及到手动解决冲突的问题。

6.4、克隆代码到本地

  • 37
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱里承欢。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值