Git基础入门,包括Git的基本概念、常用指令、分支管理、多人协作等内容。

简单的git指令

1
2
3
4
5
6
7
8
9
10
git init 					# 初始化一个新的Git仓库。
git add <file> # 将文件添加到暂存区。
git commit -m <message> # 将暂存区的内容提交到仓库,并附上提交信息。
git reset --hard commit_id # 将当前分支的头指针移动到指定的提交,同时重置工作目录和暂存区到这个提交状态。
git log # 显示仓库的提交历史记录。
git reflog # 显示所有的引用记录,包含所有的提交、重置和合并操作的历史。
git checkout -- file # 从当前分支的最新提交中恢复指定文件,撤销对该文件的未提交更改。
git reset HEAD <file> # 将指定文件从暂存区移除,但保留工作目录中的更改。这样可以让文件恢复到未暂存状态。
git rm # 删除文件,并将删除操作添加到暂存区。
git fetch # 从远程仓库获取最新的更改,但不合并到当前分支。

概念

工作区和暂存区的概念

工作区 --> git add --> 暂存区 --> git commit–> 分支

分支管理

创建和合并

查看分支: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>

解决冲突

合并时发现冲突,解决后再次commit

git-01-2024-07-31-17-28-58

分支管理策略

git-01-2024-07-31-17-29-07

Bug分支

  1. 将当前的dev分支隐藏

    1
    git stash
  2. 切换到需要debug的分支,建立临时分支(issue-101)debug

    1
    2
    git checkout master
    git checkout -b issue-101
  3. 修复,提交,合并

    1
    2
    3
    4
    git add
    git commit -m ""
    git switch master
    git merge --no-ff -m "merged bug fix 101" issue-1011
  4. 切换回原分支

    1
    2
    3
    git switch
    git stash list
    git stash pop/git stash apply + git stash drop
  5. 将修改内容复制到dev分支(只复制debug的修改内容)

    1
    git cherry-pick

feuture分支

1
2
3
git switch -c
git add
git commit -m

如果此时要删除这个分支:

1
git branch -d

因为该分支还未合并,需要强制删除

1
git branch -D

多人协作

查看远程仓库信息:

1
git remote -v

推送分支:

1
git push origin master/dev/...

抓取分支:

1
git clone

创建远程的开发分支到本地:

1
git checkout -b dev origin/dev

创建本地dev分支与远程origin/dev分支的链接:

1
git branch --set-upstream-to=origin/dev dev

创建标签

1
git tag <Tag> <commit id>

标签删除:

1
git tag -d

推送标签:

1
git push origin <tagname>

git 应用的一次实例

背景:通过git clone代码,分支版本错误
解决:

  1. 通过 git branch -a 查看了当前的branch分支,[remotes/origin/HEAD->origin/cicv-23.10],可以看到当前指向的远端是cicv-23.10

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    zhangxuyang@ubuntu-virtual-machine:~/kernel$ git branch -a          
    * cicv-23.10
    remotes/origin/CrossOsDriver-dev
    remotes/origin/HEAD -> origin/cicv-23.10
    remotes/origin/cicv-23.10
    remotes/origin/cicv-23.10-codec-v5xx
    remotes/origin/cicv-24.1
    remotes/origin/cicv-24.1-cross-serial
    remotes/origin/cicv-24.1-crossdriver-gpio
    remotes/origin/cicv-24.1-crossdriver-gpio-dev
    remotes/origin/cicv-24.1-crossdriver-reset
    remotes/origin/cicv-zjo-reset
    remotes/origin/guoweikang/drop_phy
    remotes/origin/guoweikang/update_i2c
    remotes/origin/main
    remotes/origin/tanghanwen_compile_fix
  2. 通过 git checkout -b cicv-24.1 origin/cicv-24.1 这个命令,将分支切换到远端的/cicv-24.1

    1
    2
    3
    4
    zhangxuyang@ubuntu-virtual-machine:~/kernel$ git checkout -b cicv-24.1 origin/cicv-24.1
    正在更新文件: 100% (43255/43255), 完成.
    分支 'cicv-24.1' 设置为跟踪来自 'origin' 的远程分支 'cicv-24.1'
    切换到一个新分支 'cicv-24.1'
  3. 通过 git remote -v 来查询显示当前 Git 仓库配置的所有远程仓库及其对应的 URL,并附带显示详细信息。

    1
    2
    3
    4
    zhangxuyang@ubuntu-virtual-machine:~/kernel$ git remote -v
    origin http://10.14.93.219/cicv/kernel.git (fetch)
    origin http://10.14.93.219/cicv/kernel.git (push)
    zhangxuyang@ubuntu-virtual-machine:~/kernel$

其中:
远程仓库名称 origin:origin 是默认的远程仓库名称,通常用于指向克隆仓库的原始来源。
URL http://10.14.93.219/cicv/kernel.git:这个 URL 是远程仓库的地址。在这个例子中,它指向一个通过 HTTP 协议访问的 Git 仓库,托管在 10.14.93.219 这台服务器上。
操作类型:
(fetch) 表示这是用于拉取(fetch)数据的 URL。
(push) 表示这是用于推送(push)数据的 URL。

  1. 通过 git log --oneline 命令来查看变更记录
    1
    2
    3
    4
    zhangxuyang@ubuntu-virtual-machine:~/kernel$ git log --oneline
    09a7c82458b8 (HEAD -> cicv-24.1, origin/cicv-24.1) Merge branch 'guoweikang/rt_release' into 'cicv-24.1'
    bffeff34705b support bst PREEMPT_RT release
    3363a6ccfc94 Merge branch 'tanghanwen/compiler_fix' into 'cicv-24.1'

习题及解答

  • 什么是git bisect? 怎么用?通过自己构造一个场景 演示使用场景和方法
  • 什么是git rebase? 怎么用? 如果冲突了该怎么解决?解决思路是什么? 通过自己构造一个场景 演示使用场景和方法
  • 使用git rebase 完成 合并多个提交;删除某个提交等动作
  • 什么是git 多远程仓库? 有什么用? 请构造一个 cherry-pick + 多远程仓库的使用场景

Git Bisect

Git Bisect 命令可以快速找到引入特定错误的提交,通过二分查找的方式,可以快速定位到导致问题的那个提交。

git-01-2024-07-31-17-29-28

Git Bisect 使用方法

  1. 开始 Bisect: git bisect start
  2. 设置好/坏提交: 告诉 Git 最早的好提交(通常是最近的已知好版本)和最早的坏提交(通常是最新版本,假设其中包含 bug)。
    • git bisect good <good-commit>
    • git bisect bad <bad-commit>
  3. Bisect 过程: Git 会自动检查出中间点,并将工作目录恢复到该提交的状态。
    • git bisect nextgit bisect skip 根据测试结果继续进行二分查找。
  4. 结束 Bisect: 当找到有问题的提交时,可以使用 git bisect reset 来退出 bisect 模式并清理工作目录。

使用场景演示

假设有一个项目,最近出现了一个 bug,想找出是哪个提交引入的这个 bug。

  1. 确定最早的好提交和最晚的坏提交。

    • 最早的好提交: commit-a1b2c3d
    • 最晚的坏提交: HEAD
  2. 开始 bisect:

    1
    2
    3
    git bisect start
    git bisect good commit-a1b2c3d
    git bisect bad HEAD
  3. Git 会自动切换到中间的一个提交,并提示测试是否存在问题。

  4. 测试代码,如果存在 bug,则运行 git bisect bad,如果没有则运行 git bisect good

  5. 重复步骤 3 和 4 直到找到引入 bug 的提交。

  6. 一旦找到有问题的提交,使用 git bisect reset 退出 bisect 并清理工作目录。


Git Rebase

Git Rebase 是一种操作,用于将一个分支上的更改应用到另一个分支的顶部。这有助于保持线性的提交历史,使提交历史更清晰易读。

git-01-2024-07-31-17-29-46

如何使用 Git Rebase

  1. 开始 Rebase: git rebase <branch-name>
  2. 处理冲突: 如果在 rebase 过程中遇到冲突,Git 会暂停并提示手动解决冲突。
  3. 完成 Rebase: 解决完所有冲突后,使用 git add 添加已解决的文件,然后使用 git rebase --continue 继续 rebase。

使用场景演示

假设有两个分支:mainfeature,把 feature 分支的更改应用到 main 的顶部。

  1. 切换到 feature 分支:

    1
    git checkout feature
  2. 开始 rebase:

    1
    git rebase main
  3. 如果有冲突,手动解决冲突,然后添加文件并继续 rebase:

    1
    2
    git add <conflicted-file>
    git rebase --continue

删除某个提交

  1. 查看提交历史:

    1
    git log
  2. 找到要删除的提交,并开始 interactive rebase:

    1
    git rebase -i <commit-before-deleted-commit>~1
  3. 在文本编辑器中,找到要删除的提交行,并将其前缀从 pick 改为 drop

  4. 保存并关闭编辑器,Git 会自动应用这些更改。

合并多个提交

  1. 开始 interactive rebase:

    1
    git rebase -i <last-commit>~n
  2. 在文本编辑器中,找到要合并的提交,并将其前缀改为 squashs

  3. 保存并关闭编辑器,Git 会提示编辑 commit message。


Git 多远程仓库

Git 多远程仓库 允许将本地仓库与多个远程仓库同步。这在协作开发中很有用,比如同时与不同的团队合作或者需要从不同的源拉取代码。

使用场景演示

假设有一个项目,需要从两个不同的远程仓库拉取代码:一个是公司的内部仓库(origin),另一个是开源社区的仓库(upstream)。

  1. 添加新的远程仓库:

    1
    git remote add upstream https://github.com/community/project.git
  2. 查看远程仓库:

    1
    git remote -v
  3. 拉取上游仓库的更改:

    1
    git fetch upstream
  4. 检查上游仓库的分支:

    1
    git branch -r
  5. 将上游仓库的某个分支合并到当前分支:

    1
    2
    git checkout main
    git cherry-pick upstream/main
  6. 推送更改到默认远程仓库 (如 origin):

    1
    git push origin main