Git、github常用操作(命令讲解+操作举例)+idea集成

对于未使用过版本控制的新手来说,git中包含了大量全新的概念,需要细致查阅文档和不断使用才能对此熟悉,本文将帮助新手理解git版本控制的抽象模型,并提供git bash使用教程、idea集成教程和github使用教程帮助新手快速上手。

一、基本概念与工作流程介绍

1.1基本概念

1.1.1版本控制

版本控制(Revision control)是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史,方便查看更改历史记录,备份以便恢复以前的版本的软件工程技术。

可以直接理解为用于管理多人协助开发项目的技术

通过版本控制软件,可以最好的保证软件源代码的安全性和开发过程的高效率。

1.1.2工作区域

Git的工作区域可以分为4个:工作区、暂存区、本地仓库和远程仓库。

可以理解为会将各版本的代码存储在4个不同的地方(这也是我学git时,老师讲要是能把git上传过的项目删干净,就已经学成了的原因)。

  • 工作区:正常编写代码的空间。
  • 暂存区(stage/index):临时存放改动的空间,实际上只有一个文件。(用处就是在工作区和仓库之间分层做缓冲,将工作区的修改都add累加到暂存区,然后commit一下存储到仓库,有一个暂存区有助于方便地规划每次commit的内容,而不是直接将整个工作区内的更改全部一次存储到仓库)
  • 本地仓库:安全存放数据的位置,这里面有你提交到所有版本的数据。
  • 远程仓库:托管代码的服务器,和本地仓库类似。

1.1.3版本控制分类

常见的版本控制方式有3类:本地版本控制、集中版本控制、分布式版本控制。

  • 本地版本控制:记录文件每次的更新,可以对每个版本做一个快照,或是记录补丁文件,建议个人使用。
  • 集中版本控制:相比本地版本控制,所有的版本数据都保存在服务器上了,协同开发者需要从服务器上同步更新或上传自己的修改。(代表产品:SVN)
  • 分布式版本控制:在集中版本控制的基础上,所有版本信息仓库全部同步到本地的每个用户,每个用户那里保存的都是所有的版本数据。(代表产品:Git)

三个类型各有各的用途和优缺点,比如SVN易于管理和保证安全性,适合人数不多的项目开发;Git适合分布式开发,可以很容易的解决冲突等。

1.2工作流程

即Git基本功能的使用方式,之前已经讲了git的4个工作区域,这里提一下提交文件的过程(更详细内容在后续三、Git常用本地命令中讲解):

  1. 在工作中添加、修改文件。(我新建了OtherOBJ.txt在resources目录)
  2. 使用git add命令将需要进行版本管理的文件放入暂存区域。(我使用git add .指令将当前目录下所有文件添加到了暂存区,使用git status可以看到多了一个新文件OtherOBJ.txt,原先为untracked文件)
  3. 使用git commit命令将暂存区域的文件提交到git仓库,这样git的版本树上就多了这一次的提交。(使用git log命令,即可查看本地的版本树,发现相比origin远程仓库多了一个版本)
  4. 使用git push命令将本地仓库中的分支合并到远程仓库。(第一个参数origin为远程仓库名,第二个为本地分支名,第三个为远程分支名)

即可完成提交文件,不过这是同一个git账号的情况下的使用方式,在不同账号下需要进行pullRequest,具体内容将在六、GitHub使用教程中讲解;此外本处只讲解了提交文件的过程,并未涉及到版本管理的内容,具体将在第三、四章讲解。

二、Git安装与配置

2.1安装

下载git地址:https://git-scm.com。(安装就一直next就行,不用配置什么东西,可以改一下安装目录)

下载并安装完成后,将在Git目录下看到两个可执行文件:

Git Bash是linux风格的命令行,Git Cmd是windows风格的,大多使用的都是Git Bash。另外,Git Bash支持大部分bash的操作,可以执行cd、mkdir、ls等等文件操作,也可以使用vim进行文件编辑。(直接当做终端用就行)

2.2配置文件

git的配置文件有三种,分别对应不同的作用域:(优先级:local>global>system)

  • system级:系统级,对应该计算机系统所有用户和所有项目的值。(Linux的/etc/gitconfig)
  • global级:用户级,对应当前登录的用户,不同用户的配置文件不同。(Linux的~/.gitconfig)
  • local级:项目级,不同的git项目可以使用不同的配置。(项目中的.git/config)

可以使用global config --system|global|local -l命令查看所有配置。

更多命令可以输入global config直接查看。

2.3账户管理

我们在使用远程仓库的时候,需要将本机的ssh公钥存储在远程仓库中,以保证安全传输,这就需要我们在git bash中创建一个账户然后将其储存到远程仓库中(以github为例)。

  1. 在配置文件中设置账户和邮箱:git config --local user.name|user.email。本人已经设置过全局账号了,这里就在local中设置账号举例了:(你需要使用的是--global参数)
  2. 生成ssh密钥对:ssh-keygen -t rsa -C "xxx@xx.com"会要求你输入两次密码,这是用来加密你的私钥的,使用私钥的时候要用到,如果不输入就是不加密。生成两个文件,pub是公钥,没后缀的是私钥。
  3. 将公钥添加到github中。然后就加进去了,然后你的git就能使用这个远程仓库了。

可输入ssh -T git@github.com判断有无成功。(如果警告无法验证github服务器端的指纹,就直接输入yes,信任就完事了,如果担心安全性就去查一下github的指纹,直接指定)

三、Git常用本地命令

在讲解Git的命令时,我们会从具体命令和使用举例两方面介绍命令,同时讲解一下git中的特殊结构如head、master的含义等,以帮助构建对git版本控制方式的理解。

3.1创建仓库

通常创建一个仓库有两种方式,使用init将自己的编程文件变成仓库和使用clone/pull克隆远程仓库。(git clone在四、Git常用远程命令中讲解)

新建一个Git代码库的指令:git init

现在仓库就被建立起来了。但是现在还没有任何分支,使用git log指令会发现没有master;使用git status会发现所有文件都是untracked模式。

使用git init [project-name]可以指定项目名称,默认为文件夹名称。

3.2文件保存与恢复

版本控制就是对文件的版本控制,要对文件进行修改、提交、恢复等操作,在不同的工作区域中的文件会具有不同的文件状态,在讲解对应指令前我们需要先介绍文件的四种状态。(注意:GIT不关心文件两个版本之间的具体差别,而是关心文件的整体是否有改变,若文件被改变,在添加提交时就生成文件新版本的快照,而判断文件整体是否改变的方法就是用SHA-1算法计算文件的校验和。)

3.2.1文件状态

文件具有多种状态:

  • untracked(工作区):未跟踪(未入库),可以使用git add指令直接将其添加到仓库(Staged)中。
  • Unmodified(工作区):已入库,未修改,即工作区中的文件与仓库中的文件是一致的,使用git rm --cached指令可以将其还原为untracked状态。
  • Modified(工作区):已入库,并已修改,可通过git add指令可进入暂存staged状态,也可以使用git checkout指令丢弃修改,返回到unmodify状态(git checkout:从库中取出文件, 覆盖当前修改)。
  • Staged(暂存区):暂存状态,执行git commit命令可将修改同步到库中,这时库中的文件和本地文件又变为一致,文件为Unmodify状态;执行git reset HEAD filename指令可取消暂存,文件变为modified状态。
  • commited(仓库):仓库中的文件(实际上不是一种状态,在文件提交后,会默认回到Unmodifed状态)。

可使用git status查看所有文件状态信息;或使用git status filename查看指定文件状态信息。

刚才init项目之后,是有git status发现所有文件都为untracked,可使用git add .将其全部变更为staged状态(存入暂存)。

(注意:warning: LF will be replaced by CRLF in为自动转换的警告,会将文件中的换行符更变为适配当前操作系统的编码,不用在意)

Change to be commited说明已经在staged状态,准备提交了;如果是Changes not staged for commit状态,就说明还未存入暂存区,不是staged状态。

commit后,状态就变成commited:

新建一个文件,会成为untracked状态:

add到staged之后再修改,就会变成Modified:

可使用git checkout还原:(内容也被还原)

接下来将讲解各类文件操作指令。

3.2.2文件添加指令

工作区中会有一个隐藏目录.git,这个不是工作区,而是Git的版本库。 Git的版本库里存了很多东西,其中最重要的就是称为stage(或index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针HEAD。

add指令就是将文件添加到stage(即状态从untracked到staged)。

  • git add [file1] [file2]:添加指定文件到暂存区。
  • git add [dir]:添加指定目录到暂存区,包括子目录。
  • git add .:添加当前目录的所有文件到暂存区。

3.2.3文件删除指令

有add,自然有撤销add的操作。

  • git rm --cached:从暂存区删除文件,工作区不变,不使用cached指令将导致物理文件也被删除。(文件状态从staged到untracked)
  • git reset HEAD:使用仓库的目录树重写暂存区的目录树。

其他相关指令:

  • git clean [options]:移除所有未跟踪文件,参数-d表示包含目录,-f表示强制清除。
  • git mv beforename aftername:改名,把beforename改为aftername。

3.2.4文件差异查看

git status可以查看哪些文件被修改,但无法查看具体的修改内容。

git diff指令用于查看修改内容。

  • git diff [files]:查看文件修改后的差异(从Unmodifed或Staged到Modifed)。-表示删除,+表示增加

  • git diff --cached:比较暂存区和最后一次提交 (HEAD) 之间的差异,常用于查看尚未提交但即将提交的更改。
  • git diff HEAD~n:比较当前提交和之前的提交之间的差异,比如git diff HEAD~3将会显示当前提交和当前提交的前第三个提交之间的差异。

3.2.5文件提交指令

commit命令可以实现将暂存区的文件提交到本地仓库,并形成一个版本。

  • git commit:提交暂存区到仓库区,会让你编辑一个文本作为注释。
  • git commit -m [message]:提交暂存区到仓库区,直接输入注释。
  • git commit -v:显示所有diff信息(注意,这个指令我使用的使用一直报错Aborting commit due to empty commit message...有空说不定可以看看源码)
  • git commit -a:提交工作区自上次commit之后的变化,直接到仓库区,跳过stage。(不会提交untracked文件)
  • git commit [file1] [file2]:提交暂存区的指定文件到仓库区。
  • git commit --amend:使用一次新的commit,替代上一次提交,如果代码没有任何新变化,则用来改写上一次commit的提交信息。

提交后的返回:

使用git log可以查看过去提交的版本:

3.2.6忽略文件

.gitignore文件用于让某些其他文件不被纳入版本控制,比如临时文件。

.gitignore有特殊的匹配规则:

  1. 通配符 *:*表示匹配零个或多个字符。例如,*.log将匹配所有以.log为扩展名的文件。
  2. 问号 ?:?表示匹配一个单个字符。例如,file?.txt将匹配file1.txt、fileA.txt等。
  3. 目录分隔符 /:使用正斜杠/来表示目录。例如,/logs/将匹配项目根目录下的logs目录。
  4. 目录通配符 /**/:/**/匹配任意多层嵌套的目录。例如,logs/**/error.log将匹配logs/error.log、logs/debug/error.log等。
  5. 感叹号 !:在.gitignore中使用感叹号表示取消忽略。例如,如果你的规则中有*.log表示忽略所有.log文件,但如果你在规则中添加!important.log,则会取消忽略important.log文件。
  6. 行注释 #:在.gitignore中以#开头的行被视为注释,不会被处理。
  7. 字符类 []:可以使用字符类来匹配字符的任意组合。例如,[0-9]将匹配任何单个数字,[aeiou]将匹配任何一个元音字母。
  8. 转义字符 \:如果想匹配包含特殊字符的文件名或目录名,可以使用反斜杠\来转义这些特殊字符。例如,要匹配文件名中包含星号*的文件,可以使用file\*name。

举例:忽视当前项目下log文件夹中所有文件和文件夹,.gitignore中就是/log/。

3.2.7撤销提交

撤销提交需要将HEAD指针指向前一个commit对象,然后恢复工作区和index即可。但这会丢弃工作区和index的改动。

  • git reset --hard HEAD~1:撤销上一次的提交。
    • --soft:重置仅改变HEAD的位置,保留更改暂存区和工作目录中的内容。
    • --mixed(默认选项):重置HEAD的位置,清除暂存区,但保留工作目录中的更改。
    • --hard:重置HEAD的位置,清除暂存区和工作目录中的所有更改,慎用,因为会永久删除未提交的更改。

(使用git reset --hard HEAD~1回退到第5次提交??,忽略了第六次提交)

  • git reset:指定commit-id来返回到指定版本。

(使用git reset回退到第2次提交,忽略了第3、4次提交)

  • git revert :生成一个新的提交,使仓库回滚到指定的commit版本。

(以第三次提交与第一次相同内容的方式,从第二次提交回滚到第一次提交)

3.2.8文件恢复指令

我们已经知道文件有四个工作区域,暂存区中存储了工作区的修改,仓库中存储了过去的commit版本。接下来的恢复就是尝试使用暂存区的更改来恢复工作区和使用旧的commit版本恢复工作区和暂存区。

主要使用的恢复指令有两个,git checkout(从stage中恢复)和git reset(从repo中恢复)。

  • git reset:已在3.2.7中讲解,恢复到仓库中的版本。
  • git checkout:用于撤销工作区中的修改,使用stage中的内容进行重写工作区。
    • git checkout HEAD:汇总显示工作区、暂存区与HEAD的差异。(我修改了工作区中的v.txt,并且将untracked的v2.txt添加到了stage)

    • git checkout -- filename:用暂存区中filename文件来覆盖工作区中的filename文件,即取消自上次执行commit、add以来的本地修改。

(创建一个文件,并添加到stage)

(现在是stage状态,进行更改,再使用checkout进行恢复)

(再看v3,txt内容,发现就是刚add时的内容)

    • git checkout -- .:用暂存区的所有文件直接覆盖本地文件。
    • git checkout commit_id -- file_name:使用指定版本的commit中的指定文件替换工作区和暂存区中的对应文件。

3.2.9查看日志

查看日志通常使用git log和git reflog指令。

  • git log:查看提交日志。
    • git log --graph:以图形化的方式显示提交历史的关系。
    • git log path:查看特定文件或目录的提交历史,包括谁在何时进行了更改以及具体的修改内容。
  • git reflog:显示这个仓库中所有的分支的所有更新记录,包括已经撤销的更新。(当前只有master一支)

3.3分支操作

之前的所有操作,都是在单一分支中进行的,没有涉及到分支操作。在进行分支操作的讲解前,我们要先理解git的版本树、分支、head的内涵。

git的版本管理是树状结构的,每一个commit都是一个节点,只有一个前继节点(合并形成的commit有多个前继节点),可以有多个后继节点。

(图片仅供参考,合并操作导致一个节点有了多个前继节点)

而分支就是一个指向节点的指针,一个分支不会记录一连串的commit,而是只指向一个commit节点。(之所以图片上一个分支看上去有一条线,但实际上那是历史记录,记录了该分支所指向过的节点)

master也是一个指针,其他的dev、release等也是一个指针。

head意为当前使用的分支,实际上是一个指向指针的指针。

示意图:

而我们的分支操作,实际上就是操作这颗版本树、分支指针和head指针。

3.3.1新建分支与切换分支

  • 新建一个分支的指令为git branch [branch-name]。

开始时的结构图(默认情况):

在使用了指令git branch dev后的结构图:(即新建一个指针)

目前还是在master分支。

  • 切换分支使用的是git switch指令(也可以使用git checkout指令,但是不如git switch直观)。

切换后的示意图:(现在所在的就是Dev分支,即变动了Head指针指向的分支指针)

  • 创建一个新分支并立即切换到该分支的指令:git switch -c 新分支名(或git checkout -b 新分支名)
  • 新建一个分支,指向指定commit:git branch [branch] [commit](如执行git branch dev2 d2a0862ad5d370e5edda59d081414bab7b801790)

结构图:

只显示了该分支当前的commit。

  • 新建一个分支,追踪指定的远程分支:git branch --track [branch] [remote-branch](详情会在后续四、Git常用远程命令中讲解)

3.3.2查看分支

  • git branch:查看本地所有分支。

  • git branch -r:查看所有远程分支。

  • git branch -a:查看所有本地分支和远程分支。

3.3.3分支合并

合并分支从之前提到的结构图上看,可以理解是,使用两个分支指针指向的节点生成一个新节点。

合并使用指令:git merge [branch](合并指定分支到当前分支)、git rebase [branch],合并时有两种情况:

  • 不存在冲突:即指定的分支中更改的文件在当前分支中都没有更改过(之前提到git记录的是文件的更改)。

如创建一个分支,指向原master所在的commit,然后提交了新的commit,再把Head切换到master。

结构图:

(然后执行合并操作)

现在查看master分支:(发现dev中更改已经出现在了master)

结构图:

  • 存在冲突(先讲merge,再讲rebase):即指定的分支中更改的文件在当前分支中也更改过,如果同一个文件在合并分支时都被修改了则会引起冲突。

现在我将在master中提交一个文件的修改,在dev中也提交同一个文件的修改:

(准备工作)

当前结构图:

开始合并:(提示冲突,需要修改冲突文件后重新提交)

修改clash.txt后提交。(vim查看,Git用>>>>>>标记出不同分支的内容,其中>>>>dev2 是指dev2上修改的内容)

图形化查看修改后结果:

结构图:

查看结果发现master中文件为合并后内容,dev中内容未变。

  • git rebase:(使用这个指令的难度较大,此处仅粗略讲解,详细内容可看Git - 变基 (git-scm.com))同样是合并代码,但在处理冲突时,是首先找到这两个分支的最近共同祖先commit4,然后对比当前分支(dev)相对于该祖先的历次提交,提取相应的修改并存为临时文件,然后在commit5的基础上将这些文件再次提交,形成一个新的commit(commit6‘),但会导致原来的commit6消失。

结构图:

(开始状态)

对Dev执行rebase之后:

3.3.4删除分支

  • 删除本地分支命令:git branch -d [branch-name](-D强制删除)。
  • 删除远程分支命令:git branch -d -r [remote/branch]。(注意:删除的是本地的分支指针,不是删除远程仓库中的分支)

注意:git不能删除当前所在(head指向)的分支,需要切换后再删除;对于未合并的分支,需要使用-D强制删除。

四、Git常用远程命令

4.0管理远程仓库

  • git remote:查看远程仓库列表(查看本地仓库已经关联的远程仓库列表)。
  • git remote -v:查看远程仓库详细信息。

  • git remote add :将远程仓库URL添加到本地仓库的远程仓库列表中,以便与它交互。

4.1克隆&提交&分支管理

  • git clone:将远程仓库克隆到本地,创建一个本地的工作副本。从github获得一个远程仓库URL,然后克隆,如:

  • git push :将本地分支的更改推送到远程仓库。
    • --force:强行推送当前分支到远程仓库,即使有冲突。
    • --all:推送所有分支到远程仓库。
    • git push ::将本地分支的更改推送到远程仓库的指定远程分支。
    • git push --delete :删除远程分支。
  • git fetch :从远程仓库获取最新的更改,但不会自动合并到本地分支。
    • git fetch :取回特定分支的更新。
  • git pull :从远程仓库拉取最新更改并自动合并到当前分支。
    • git pull --rebase ::需要采用rebase模式合并。

五、Git在idea中的使用

(请优先查看前文内容,idea集成可理解为仅是将bash命令做了可视化封装。)

5.1Setting中配置Git

(我这里添加了中文插件,设置都是大差不差,只要设置git的可执行文件地址就好了。)

5.2创建本地Git仓库

即可使用git进行提交到本地仓库。

可以在idea中进行可视化操作,与直接使用git bash没什么差别。

右下角可以查看分支。

5.3其它操作

idea中还集成github中的许多操作,比如直接将项目上传github等,可自行了解。

六、GitHub使用教程

在之前git的讲解中,我们已经介绍了如何建立远程仓库(2.3账户管理)、如何使用远程命令(四、Git常用远程命令)。这里将介绍在GitHub的界面中做一些可视化的git操作和其他特殊操作(如fork&pull request等)。(更详细的内容建议查看官方文档:GitHub Docs有中文版)

6.1创建仓库&分支&上传更改

6.1.1创建仓库

github中可以直接创建远程仓库。

6.1.2创建分支

6.1.3添加文件

添加完成。

6.1.4编辑文件

进入编辑。

然后即可提交。

6.2提交、同意pull request

我们之前已经创建了一个分支masters并添加了一个文件testGit,现在需要将这个master2合并到master主分支。

pull request是 GitHub 上协作的核心。 打开pull request后,可以提出更改,要求某人审查和提取你的贡献并将其合并到其分支中。 pull request将显示两个分支中内容的差异。 变化、增减以不同的颜色显示。

我们也可以自行进行拉取请求来熟悉流程。

  1. 创建一个pull request:(右侧可以添加一些信息,这里就先忽略了)
  2. 再进入pull request选项卡就能同意了。

6.3参与他人项目

如果不具有对存储库的写入权限,但是想要参与他人的项目,就需要使用fork和pull request功能。

6.3.1创建fork、发送pull request、merge pull request和评价

然后更改自己远程仓库中的文件,再pull request到对应的账户的远程仓库中。

(已完成更改)

点击new pull request。

指明目标仓库、分支和自己仓库、分支,发送pull request。

然后等待对方同意或评价即可。

6.3.2加入项目合作者

也可以让该项目的作者把你加入项目合作者里面,就直接有写入权限了。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值