3410 字
17 分钟
Git基础操作

1.Git介绍#

1.1.Git是什么#

Git是目前世界上最先进的分布式版本控制系统(没有之一)。

1.2.分布式与集中式#

SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活,干完后,需要把自己做完的活推送到中央服务器。集中式版本控制系统是必须联网才能工作,如果在局域网还可以,带宽够大,速度够快,如果在互联网下,如果网速慢的话,就纳闷了。

Git是分布式版本控制系统,那么它就没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在自己的电脑上。既然每个人的电脑都有一个完整的版本库,那多个人如何协作呢?比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,你们两之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。

2.安装Git#

2.1.在Linux上安装#

首先,你可以试着输入git,看看系统有没有安装Git:

Terminal window
$ git
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git

像上面的命令,有很多Linux会友好地告诉你Git没有安装,还会告诉你如何安装Git。

如果你碰巧用Debian或Ubuntu Linux,通过一条sudo apt install git就可以直接完成Git的安装,非常简单。

如果是其他Linux版本,请参考发行版说明,例如,RedHat Linux可以通过命令sudo yum install git安装。没有包管理器的发行版可以自行下载源码编译安装,仅适合老鸟。

2.2.在Windows上安装#

直接从Git官网直接下载安装程序,然后按默认选项安装即可。安装完成后,在命令行中输入git,返回信息未安装成功

2.3.配置Git#

安装好Git后,还需要最后一步设置,在命令行输入:

git config --global user.name "Your Name"
git config --global user.email "[email protected]"

查看git config 配置信息:

git config --list

注意git config命令的--global参数为全局参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。

Git 的配置优先级:

  1. system(系统级)
  2. global(当前用户级)
  3. local(当前仓库级,优先级最高)

3.创建版本库#

什么是版本库呢?版本库又名仓库(Repository),可以理解为一个目录,在这个目录中所有的文件都会被Git管理起来,每个文件的改动,都可以被Git跟踪,或者可以还原。

3.1.创建仓库#

git init <目录>

3.2.克隆仓库#

git clone <仓库地址>

4.工作区和文件状态#

Git有三个主要区域:工作区、暂存区和本地仓库,它们定义了文件的不同状态。文件在工作区中修改,可以通过 git add 命令将其添加到暂存区,最后通过git commit将暂存区的修改提交到本地仓库。

4.1.文件状态#

  • 未跟踪(untracked): Git仓库尚未管理的文件,通常是新添加的文件。
  • 已修改(modified): 文件已被修改但尚未添加到暂存区。
  • 已暂存(staged): 文件已经被添加到暂存区,并已包含在下一次提交的快照中。
  • 已提交(committed): 文件已被永久保存在本地仓库中。

4.2.工作区域#

  • 工作区 (Working Directory): 你直接进行编辑和修改的项目文件所在地。
  • 暂存区 (Staging Area): 一个中间区域,用于存放你打算在下一次提交时包含的文件列表。
  • 本地仓库 (Repository): 存储了所有已提交版本的数据的区域,也就是 .git 目录。

4.3.查看暂存区中的内容#

git ls-files

5.添加和提交文件#

5.1.常用命令#

1)添加文件#

git add <file>

2)提交文件#

git commit -m <message>

3)查看仓库状态#

git status

4)查看文件差异#

git diff <file>

5)查看提交记录#

git log # 查看提交记录
git log --oneline # 查看简洁的提交记录
git log --pretty=oneline

6. 版本回退#

在Git中,用HEAD表示当前版本,上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100

$ git reset --hard HEAD^
HEAD is now at e475afc add distributed

查看历史操作,使用 git reset --hard commit id 回退到之前的版本。

$ git reflog
90244a0 (HEAD -> master) HEAD@{0}: reset: moving to HEAD^
7c524f7 HEAD@{1}: commit: append GPL
90244a0 (HEAD -> master) HEAD@{2}: commit: add distributed
3730607 HEAD@{3}: commit (initial): wrote a readme file

6.1.工作区和暂存区#

工作区(Working Directory):就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区。

暂存区:在工作区的隐藏目录 .git 中, 存放了当前仓库的版本库,版本库中最重要的就是称为stage(或者叫index)的暂存区 ,提交的文件会先被放入到暂存区中,在提交是会被一次性提交。

6.2.撤销修改#

git checkout -- <file> 可以丢弃工作区的修改。其中分为两种情况:一种是 file 在修改前没有没存放到暂存区中,撤销后文件回到上个版本。另一种是 file 已经添加到暂存区后,又进行了修改,撤销后会回退到和暂存区状态一样的版本。

$ git checkout -- readme.txt

当已经将错误的修改提交到暂存区时该如何修改,我们可以回退到现在的版本即可。

git reset --hard HEAD

6.3.版本回退命令总结#

  • 回退版本git reset --hard <commit ID>

  • 回退到上个版本git reset --hard HEAD^

  • 查看历史操作git reflog

7.远程仓库#

7.1.创建SSH Key#

ssh key 通常存放在用户主目录下的 .ssh 目录中

Terminal window
ssh-keygen -t rsa -C "[email protected]"

创建完成后会在用户主目录下的 .ssh 目录中会有id_rsaid_rsa.pub两个文件,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。

7.1.1上传公钥给Github#

点击你的头像 —> Settings —> SSH and GPG keys —> New SSH key

image-20251118150733912

7.1.2.配置Git强制使用刚才创建的SSH key[选做]#

~/.ssh/config 中写入:

Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa
IdentitiesOnly yes

7.1.3.测试SSH 能否正常连接#

第一次会提示 Are you sure you want to continue connecting (yes/no)?,输入 yes 后,如果密钥正确并且 GitHub 账号已绑定公钥,会返回类似:

PS C:\Users\Owen_W> ssh -T [email protected]
Hi Owenwoow! You've successfully authenticated, but GitHub does not provide shell access.

-T Disable pseudo-terminal allocation. (不分配伪终端,只进行认证)

7.2.添加远程仓库#

首先,登陆GitHub,然后,在右上角找到加号点击“New repository”按钮,创建一个新的仓库:

image-20251118154955271

在Repository name填入learngit,其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库:

image-20251118155220369

目前,在GitHub上的这个 learngit 仓库还是空的,GitHub告诉我们,可以从这个仓库克隆出新的仓库,也可以把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库。

现在,我们根据GitHub的提示,在本地的learngit仓库下运行命令:

$ git remote add origin https://github.com/Owenwoow/learngit.git
$ git branch -M main
$ git push -u origin main

添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。然后,就可以把本地库的所有内容推送到远程库上。

$ git branch -M main
$ git push -u origin main

简单讲解一些这两条参数:

  • git branch -M main 将当前分支强制重置为main。

  • git push -u origin main 这是一个推送分支到远程仓库并设置 upstream 的命令。

    • -u:为本地分支设置上游(upstream),即在未来使用 git pushgit pull 时不需要再指定 origin main,

    • origin:远程仓库的名称(默认)

    • main:要推送的分支名称。

如此我们就将本地仓库推送到了Github上,在GitHub页面中看到远程库的内容已经和本地一模一样的内容。

image-20251118155546727

7.3.SSH警告#

当你第一次使用Git的clone或者push命令连接GitHub时,会得到一个警告:

The authenticity of host 'github.com (xx.xx.xx.xx)' can't be established.
RSA key fingerprint is xx.xx.xx.xx.xx.
Are you sure you want to continue connecting (yes/no)?

这是因为Git使用SSH连接,而SSH连接在第一次验证GitHub服务器的Key时,需要你确认GitHub的Key的指纹信息是否真的来自GitHub的服务器,输入yes回车即可。

Git会输出一个警告,告诉你已经把GitHub的Key添加到本机的一个信任列表里了:

Warning: Permanently added 'github.com' (RSA) to the list of known hosts.

这个警告只会出现一次,后面的操作就不会有任何警告了。

7.4.删除远程库#

如果添加的时候地址写错了,或者就是想删除远程库,可以用git remote rm <name>命令。使用前,建议先用git remote -v查看远程库信息:

$ git remote -v
origin [email protected]:Owenwoow/learngit.git (fetch)
origin [email protected]:Owenwoow/learngit.git (push)

然后,根据名字删除,比如删除origin

$ git remote rm origin

此处的“删除”其实是解除了本地和远程的绑定关系,并不是物理上删除了远程库。远程库本身并没有任何改动。要真正删除远程库,需要登录到GitHub,在后台页面找到删除按钮再删除。

7.5.克隆远程仓库#

从远程仓库 git clone 下来的仓库已经自动绑定了远程仓库,并且默认把远程仓库命名为 origin,所有我们只需要输入以下命令即可:

git clone [email protected]:Owenwoow/learngit.git

image-20251118161356568

8.分支管理#

8.1.创建与合并分支#

分支的原理#

首先我们需要理清Git的存储方式,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向mastermaster才是指向提交的,所以,HEAD指向的就是当前分支。

一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:

HEAD
master
┌───┐ ┌───┐ ┌───┐
│ │───▶│ │───▶│ │
└───┘ └───┘ └───┘

每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长。

当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:

master
┌───┐ ┌───┐ ┌───┐
│ │───▶│ │───▶│ │
└───┘ └───┘ └───┘
dev
HEAD

你看,Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!

不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:

master
┌───┐ ┌───┐ ┌───┐ ┌───┐
│ │───▶│ │───▶│ │───▶│ │
└───┘ └───┘ └───┘ └───┘
dev
HEAD

假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:

HEAD
master
┌───┐ ┌───┐ ┌───┐ ┌───┐
│ │───▶│ │───▶│ │───▶│ │
└───┘ └───┘ └───┘ └───┘
dev

所以Git合并分支也很快!就改改指针,工作区内容也不变!

合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:

HEAD
master
┌───┐ ┌───┐ ┌───┐ ┌───┐
│ │───▶│ │───▶│ │───▶│ │
└───┘ └───┘ └───┘ └───┘

Git分支管理相关命令:#

  • 查看分支git branch
  • 创建分支git branch <name>
  • 切换分支git checkout <name> / git switch <name>
  • 创建+切换分支git checkout -b <name> / git switch -c <name>
  • 合并某分支到当前分支git merge <name>
  • 删除分支git branch -d <name> / git checkout -d <name>

注意: 到切换分支使用git checkout <branch>,和撤销修改则是git checkout -- <file>,同一个命令,有两种作用,确实有点令人迷惑。因此,最新版本的Git提供了新的git switch命令来切换分支。

8.2.解决冲突#

主分支和其他分支都添加了commit的情况下合并会产出异常,git会将两个版本的文件区别添加到文件中你需要手动修改。在这过程中可以使用gti status 来查看冲突文件,修改后重新提交。

用带参数的git log也可以看到分支的合并情况:

$ git log --graph --pretty=oneline --abbrev-commit
* 3e55018 (HEAD -> main) conflict fixed
|\
| * c2e37d1 (feature1) AND simple
* | cadec8c & simple
|/
* a8bf546 branch test
* 7a66518 (origin/main) hello
* a2ae1d7 add test.txt
* 7c524f7 append GPL
* 90244a0 add distributed
* 3730607 wrote a readme file

等待更新…

参考文献:#

Git基础操作
https://owenwoow.com/posts/2025/12/16/git基础操作/
作者
Owen_W
发布于
2025-12-16
许可协议
CC BY-NC-SA 4.0