Git

git部署和初始化

  • git init

    创建的一个包含工作区和版本库的常规 Git 仓库

  • git init --bare

    使用--bare选项时,创建的是一个仅包含版本库的“裸仓库”。不再生成.git目录,而是生成.git目录下的版本历史记录文件,直接存放在根目录下。

    用途:专门用于共享和协作,通常作为中央服务器上的仓库(如github/gitlab上的仓库底层),或者作为本地多项目协作的中间桥接仓库

    限制操作:不能再裸仓库中执行git add或者git commit,因为它没有工作区,无法再里面直接修改文件并提交,只能接受其他仓库的git push,或者作为git pull的来源

1
2
3
4
5
6
7
8
# git init my-repo 
# 你可以在 my-repo/ 下直接创建和编辑代码文件(工作区)
my-repo/
└── .git/ <-- 版本库(Git 内部数据)
├── HEAD
├── objects/
├── refs/
└── ...
1
2
3
4
5
6
7
# git init --bare my-bare-repo 
# 没有 .git 目录,也没有工作区,无法在这里写代码
my-bare-repo/
├── HEAD <-- 版本库内容直接放在根目录下
├── objects/
├── refs/
└── ...

git一般工作流程

  • 克隆git远程仓库作为工作目录
  • 在克隆资源上添加或修改文件
  • 更新资源
  • 提交修改/解决合并冲突

image-20260919150517234

git基本概念

1、本地仓库

1
2
3
4
5
6
7
工作区(Working Directory)   ← 你正在编辑的文件
↓ git add
暂存区(Staging Area / Index) ← 准备提交的内容
↓ git commit
本地仓库(Repository) ← 已经提交的历史版本
↓ git push
远程仓库(Remote)

image-20260919150923010

1)、左侧为工作区,右侧为版本库。版本库中标价”index”为暂存区,标记“master”是master分支所代表的目录树
2)、”HEAD”实际指向”master”分支的一个”游标”
3)、”object”标记区域为git对象库,位于./git/objects目录下包含了创建的各种对象及内容
4)、党对工作区新增或修改时,暂存区的目录树被更新,同时工作区修改的内容被写入到对象库中的一个新对象中,而对象的ID会被记录在暂存区的索引文件中
5)、当提交操作时,暂存区的目录树写到版本库(对象库)中,master分支会做响应的更新。即master指向的目录树就是提交暂存区的目录树。
6)、当执行git reset HEAD命令时,暂存区的目录树会被重写,被master分支指向的目录树所替换,但是工作区不受影响
当执行git rm --cached <file>, 会直接从暂存区删除文件,工作区不做改变
当执行git checkout或者git checkout --<file>会用暂存区全部或指定文件替换工作区的文件。!!会清除工作区中未添加到暂存区的改动
当执行git checkout HEAD或者git checkout HEAD <file>会用HEAD指向的master分支中的全部或者部分文件替换暂存区以及工作区文件

git配置

git提供git config 工具,专门用来配置或读取响应的工作环境变量

  • /etc/gitconfig:系统中对所有用户普遍使用的配置。若使用git config --system选项时,即读写该文件
  • ~/.gitconfig:用户目录下配置文件只适用于当前用户。若使用git config --global即访问该文件
  • 当前项目的git目录中的配置文件(.git/config):仅支持当前项目生效。每一个级别的配置都会覆盖上一层相同配置。即.git/config>~/.gitconfig>/etc/gitconfig

git 用户信息

配置个人用户名称和邮件地址:

1
2
git config --global user.name "fafafa"
git config --global user.email fafafa@test.com

如果使用了--global选项,那么更改的配置文件就是你用户主目录的那个文件,对当前计算机用户所有项目生效。

查看配置信息

1
2
3
git config --list
git config user.name
git config user.email

如果能看到不同重复变量名,即是来自不同配置文件

git基本使用

ssh链接

将客户机生成公钥,上传到git仓库SSH-Keys。之后即可在当前客户机git clone/git push

http链接

常用命令

基础命令
  • git init :初始化
  • git add main.ttt :将某个文件添加至暂存区
  • git add .:添加当前项目所有文件到暂存区
  • git commit -m '提交信息':将暂存区中的文件提交到本地保存成一个版本
  • git log:查看所有版本日志
  • git status:查看暂存区所有文件的状态
  • git diff 查看当前工作区域上一个提交版本的差异
  • git show:显示当前版本提交的详细信息,包括提交消息、作者、日期和更改的文件等
  • git reflog:显示可引用的历史版本记录。可以用来恢复本地错误操作很重要的一个命令
  • git reset --hard HEAD:清空暂存区和工作区,保持当前版本最初状态
  • git reset --head HEAD^:回滚到上一个版本
  • git reset --head HEAD^^:回滚到上上一个版本
  • git reset --head XXX:回滚到某个版本,xxx为版本号
  • git pull origin master:从远程仓库主分支拉去更新代码到当前工作区
  • git push -u origin master:把本地的 master 分支推送到远程仓库 origin
  • git pull:默认拉取、更新主分支到本地仓库
  • git push:默认推送主分支到远程仓库
分支管理
  • git checkout:切换分支;也可用于恢复文件(如 git checkout – file)
  • git checkout .:把当前目录下所有已跟踪文件的工作区内容,恢复成暂存区(index)里的版本,丢弃工作区中尚未 git add 的修改
  • git checkout -b dev:创建名为 dev 的新分支,并立即切换过去
  • git checkout dev:切换到已存在的 dev 分支
  • git branch:列出本地所有分支,当前分支前会标 *
  • git branch -d dev:删除本地 dev 分支(-d 只删已合并的分支;未合并需用 -D 强制删除)
  • git merge dev:把 dev 分支的改动合并到当前所在分支
解决冲突

1、当合并产生冲突时:

1
2
3
Auto-merging a.txt
CONFLICT (content): Merge conflict in a.txt
Automatic merge failed; fix conflicts and then commit the result.

2、打开工作区文件会看到git插入的冲突标记:

1
2
3
4
5
<<<<<<< HEAD
这是当前分支的内容
=======
这是要合并进来的分支的内容
>>>>>>> dev
  • <<<<<<< HEAD======= 之间:当前所在分支(HEAD)的版本。
  • =======>>>>>>> dev 之间:被合并分支(这里是 dev)的版本。

3、文件过多可以使用git status/git diff来定位冲突文件和状态

4、手动编辑解决冲突后,把 <<<<<<<=======>>>>>>> 这些标记删掉清理

5、编辑完成后,把文件重新加入暂存区

6、重新提交解决冲突版本

7、其他几个合并解决冲突时可使用命令:

  • git diff冲突状态下执行,会以 diff --cc 形式显示冲突文件的差异,帮你定位冲突位置。
  • git checkout --ours a.txt只保留当前分支的版本(ours = 你正在合并到的分支,即 HEAD)。
  • git checkout --theirs a.txt只保留被合并分支的版本(theirs = 要合进来的那个分支)。
  • git merge --abort:放弃合并,撤销未完成的合并,回到干净状态。

git clean -xdf 下面命令会删除新增的文件

git diff 查看已更改但未暂存内容的差异 [–staged] 已 commited 但尚未提交的内容的差异

git commit -m “add 添加新功能” 提交本地仓库

git commit –amend -m “new message” 重写最后的提交消息

git commit –amend –no-edit 修改最新的提交而不更改提交消息

git log 显示当前活动分支的提交历史

git log branchB..branchA 显示 branchA分支 上不在 branchB分支 上的提交

git diff branchB…branchA 显示 branchA分支 中的内容与 branchB分支 中的内容的差异

git push 提交远程仓库 ( 默认是向远程仓库的master分支push)

git push origin xxxxxx 提交到远程仓库的xxxxxx分支

1
2
3
4
5
6
7
8
9
10
// 功能开发完成后,将提交的本地仓库的xxxxxx分支合并到主分支,再上传到远程仓库

//首先切换到主分支
git checkout master
//拉取master分支新代码,防止主分支做了更改,合并失败( 此阶段可能会产生冲突)
git pull
//将xxxxxx分支合并到master主分支
git merge xxxxxx
//将最新代码推送到远程仓库
git push
  • 分支操作

    git branch 查看当前分支;列出所有本地分支 [-av] 列出所有分支,本地和远程

    git branch -m #重命名分支

    git checkout 切换分支 [-b 分支名] 并创建 [-d 分支名] 删除分支

工作中项目git都如何管理,冲突,push不上去如何解决

  1. 现在公司中一般的git仓库的管理方式是什么样的

    • 共用一个仓库,不同开发人员用不同分支,编写完后,再合并到主分支( 中小型公司)
    • 主仓库不直接开发,成员把仓库fork到自己的账号下,然后开发合并
  2. 代码为什么会push不上线上仓库

    • 没有权限
    • 本地比线上落后,有人比你先提交了他的功能代码( 重点)
    1
    2
    3
    4
    5
    6
    7
    8
    // 解决方案
    git pull // 然后在重新提交

    // 如果发生的冲突修改的是跟你是同一个文件的同一区域 git pull 就会产生冲突,需协商手动解决
    // 如果有冲突会有 '<<<<< HEAD' 和 '======' ">>>>>>>> 哈希值"
    '<<<<< HEAD' 到'======' 是你本地的版本代码
    '======' 到 ">>>>>>>> 哈希值" 是远程仓库版本
    // 协商手动解决完后,需重新走一遍提交流程
  3. 如何解决代码冲突

关于提交只前进一个版本的问题

1
2
3
4
5
当前分支状态:
A---B---C dev
/
D---E---F---G main

  • 普通合并

    1
    2
    git merge dev
    # 会把dev分支A-C的分支最新到main分支复制的分支记录所有合并到main分支上
  • 将分支合并后但不提交,会把修改记录或者冲突记录在工作本地;需自动提交(只会生成一个提交记录)

    1
    git merge --squash dev

视觉化的方式查看git提交记录

1
2
3
4
5
6
7
8
9
10
11
12
git log --graph --pretty=oneline --abbrev-commit

# log
* 7a3c4e7 Merge branch 'feature-xyz'
* e3f7b2a Update README.md
| * 1f3a5bc Add new feature XYZ
|/
* 2d8e155 Initial commit

# 每一行代表一个提交。
# * 表示当前分支的提交,而 | 和 / 则显示出提交的分支和合并情况。
# 缩短的提交哈希值(如 7a3c4e7)在行的开始部分,后面是提交的描述信息。

关于回退问题

如果没有冲突,直接回退:git reset –hard HEAD

说明:将工作区和暂存区都回滚到上一次提交的状态,丢掉合并带来的改动。谨慎使用,因为会丢失未提交的修改。

如果你还想保留合并引入的改动以备后续参考,可以仅回退提交状态,但保留改动:git reset –soft HEAD

这时改动仍在暂存区,可按需重新提交或修改后再提交。

git stash

  • 保存修改

    1
    2
    3
    git stash
    # 添加信息方式的保存
    git stash save "message"
  • 查看保存的所有stash列表

    1
    git stash list
  • 应用stash

    1
    2
    3
    4
    5
    6
    # 应用最近的stash记录,完成后不会删除
    git stash apply
    # 应用最近的stash记录,完成后会删除
    git stash pop
    # 应用指定stash记录
    git stash apply stash@{n}
  • 清空stash

    1
    git stash clear

worktree

功能:它 允许我们同时在多个分支上工作,并且每个分支都有自己的工作目录

场景:你正在某个分支中处理一个功能,突然之间需要在主分支(master)中修复一个关键性 bug

不使用 git worktree

  1. 在分支中存储或提交功能的更改
  2. 切换到主分支(master),在主分支中修复错误,提交修复
  3. 切换回功能分支,然后取消存储或检出更改。

使用 git worktree:

  1. 使用以下命令为主分支创建一个新的工作树到新的文件夹下
1
git worktree add ../bugfix master
  1. 并在该目录中签出主分支。现在,你可以转到 bugfix 目录并修复 bug,在这里进行的任何更改都将在主分支上进行,并不会影响其他分支。一旦完成了bug修复,则可以直接提交你的更改
1
2
cd ../bugfix
git commit -am "修复 bug"
  1. 返回到原工作目录并继续在原分支(feature)上完成之前的工作,在原分支(feature)中的完成过的代码依然存在,并且你不需要进行额外的存储和切换分支的操作
1
2
cd ../feature
// 分支功能操作