git使用笔记

1.用户初始化

1
2
git config --global user.name "Li-Ruiqi"
git config --global user.email "1009962019@qq.com"
  • 提交代码时会显示这里配置的user的信息
  • 不加--global也行,就是配置当前仓库

2.提交一个PR

1
2
3
4
5
git checkout -b feature/xxx  # 创建新分支并切换
# 进行代码修改
git add.
git commit -m "提交信息"
git push origin feature/xxx

3.切换到某个提交(commit)

如果check out到当前最新节点之前的某个节点,修改代码并提交,再切换回最新节点,会发现刚才的commit消失了,并没在该分支中

1
2
3
4
5
6
7
8
9
10
# 列出提交历史来找git graph中消失的commit
git log
# 或者
git reflog

#切换
git checkout 22dfbf1f907764c5ae70381b8191104f9af21d8c #commit号

# (可选)将此commit融入main分支
git rebase main

4.git push网络不好提交不了

通常该问题的原因都是如下的报错:

1
fatal: unable to access 'https://github.com/Li-Ruiqi777/DeepImageStitch.git/': Failed to connect to github.com port 443 after 21090 ms: Could not connect to server

出现该问题的原因是与github.com的443端口建立http协议通信失败了,解决办法如下:

  • 法1:改成ssh协议通信
1
2
git remote -v 						# 查看使用https还是ssh协议clone的仓库
git remote set-url origin <new-url> # 将协议换成ssh,更快一些
  • 法2:修改git的http协议的代理的通信端口为梯子的端口(clash可以在“设置”中看)

(1)先打开git全局配置文件

1
2
3
git config --global --edit 

export GIT_EDITOR=vim # 设置默认编辑器

(2)修改http代理为梯子

1
2
3
4
[http]
proxy = http://127.0.0.1:7890
[https]
proxy = http://127.0.0.1:7890

如果是WSL,则上面的ip得改成宿主机的IP,且WSL中必须得ping的通宿主机,ping不通看下面的链接教程

  • 法3:修改Linux全局的http(s)代理

~/.bashrc中加入下面的内容

1
2
alias proxy='export all_proxy=http://172.30.240.1:7890'
alias unproxy='unset all_proxy'

上面的ip是宿主机的ip,端口为clash的端口

参考链接:

5.添加本次修改的内容到上次commit

  • 不要用这种方法修改一个已经push到远程仓库的提交
  • 用这种方法,以后就可以先提交一个叫“备份”的commit,在解决问题后,重写修改“备份”commit的内容和提交信息了
1
2
3
4
5
6
git commit --amend 				 # 会通过core.editor指定的编辑器对commit message编辑然后提交
git commit --amend --no-edit # 不会进入编辑器,直接进行提交
git commit --amend --allow-empty # 允许合并修改内容后,实际上没有任何修改

# 配置默认编辑器
git config --global core.editor /usr/bin/vscode

6.删除一个commit

已经push的commit就删不了了,如果再用这种方式删的话,会发生冲突,还要手动进行合并操作很麻烦

  • 法1:git revert(不会修改已有的提交历史)
1
2
git reflog 			# 查看要删除的commit的hash
git revert <hash> # 创建一个新的commit,在内容上会覆盖掉<hash>中造成的修改,实现删除commit
  • 法2:git reset(会修改提交历史)
1
2
3
git reset --soft <回退大小> # 将HEAD指针回退,并将回退commit的内容放到暂存区
git reset --mix <回退大小> # 将HEAD指针回退,并将回退commit的内容放到工作区(就是硬盘中的文件)
git reset --hard <回退大小> # 将HEAD指针回退,并丢弃commit的内容

7.如何在github上搜索

这个问题非常重要,如果只在搜素框输入某些内容,那么只会匹配仓库名是你输入内容的仓库,而我们一般更希望找到仓库的README或description中包含我们输入的内容,因此可以这样索引:

1
in:readme XXX description XXX stars:>1000

8.在另一台电脑没权限操纵仓库

github的仓库中默认只有所有者和手动添加的contributer能够直接进行push操作,其他人只能通过创建一个新的分支然后PR的形式来给仓库新增代码。

如果一个人在多台电脑上想对某仓库的代码进行开发,可能会遇到该问题:在自己的电脑能够直接对该仓库进行push操作,而在另一台电脑提示没权限(可能是登录了别的github账号),可以通过以下方法解决:

1.需要以ssh的方式clone该仓库,不能用https协议

2.把正常的电脑上的~/.ssh/下的id_xxx.pub文件(github上注册了ssh key的)放到目标电脑的~/.ssh/

常用命令

1.配置

  • git config
    • 用途:用于配置 Git 的各种设置,如用户信息、文本编辑器、合并工具等。
    • 用法示例
      • 设置全局用户姓名:git config --global user.name "Your Name"。这里的--global表示该配置应用于当前用户的所有 Git 仓库。
      • 设置全局用户邮箱:git config --global user.email "your@email.com"。在每次提交时,Git 会使用这个邮箱来标识提交者。
      • 查看所有配置信息:git config --list。它会列出当前 Git 仓库(如果在仓库目录下)或全局(使用了--global)的所有配置项。

2.仓库初始化与克隆命令

  • git init
    • 用途:在本地创建一个新的空 Git 仓库。这个命令会在当前目录下初始化一个.git 文件夹,用于存储仓库的所有版本控制信息。
    • 用法示例:在一个新的项目文件夹中打开终端,输入git init,之后这个文件夹就变成了一个 Git 仓库,可以开始进行版本控制。
  • git clone
    • 用途:用于从远程仓库(如 GitHub、GitLab 等)克隆一份完整的仓库到本地。它会自动创建一个本地目录,并将远程仓库的内容下载到这个目录中。
    • 用法示例git clone [远程仓库URL]。例如,git clone https://github.com/user/repository.git会将名为repository的远程仓库克隆到本地一个同名的文件夹中。如果想自定义本地克隆后的文件夹名称,可以在 URL 后添加新的文件夹名称,如git clone https://github.com/user/repository.git my - local - repo

3.分支管理命令

  • git branch
    • 用途:用于创建、列出和删除分支。
    • 用法示例:
      • 列出所有本地分支:git branch。当前所在分支会以*标识。
      • 创建一个新分支:git branch [新分支名称]。例如,git branch feature - branch会创建一个名为feature - branch的新分支。
      • 删除一个本地分支(要求分支已合并或者使用-D强制删除):git branch -d [分支名称]。例如,git branch -d old - branch会删除old - branch分支。如果分支尚未合并,使用git branch -D old - branch可以强制删除,但会丢失未合并分支中的工作。
  • git checkout
    • 用途:用于切换分支或恢复工作区文件。
    • 用法示例:
      • 切换到已存在的分支:git checkout [分支名称]。例如,git checkout master会切换到master分支。
      • 创建并切换到新分支:git checkout -b [新分支名称]。这相当于先执行git branch [新分支名称]然后再执行git checkout [新分支名称],例如git checkout -b new - feature - branch会创建一个名为new - feature - branch的新分支并立即切换到它。

4.文件操作与提交命令

  • git add
    • 用途:将工作区的文件修改添加到暂存区,准备进行提交。
    • 用法示例:
      • 添加单个文件:git add [文件路径]。例如,git add main.py会将main.py文件添加到暂存区。
      • 添加所有修改的文件:git add.git add -A。这两个命令都可以将当前目录下所有修改、删除或新增的文件添加到暂存区,但略有区别。git add.不会添加被删除的文件,而git add -A会。
  • git commit
    • 用途:将暂存区的内容创建为一个新的提交,记录对仓库的更改。
    • 用法示例git commit -m "提交信息"。其中-m后面的内容是提交信息,用于描述这次提交所做的更改,例如git commit -m "添加用户登录功能"。如果没有使用-m,Git 会打开默认的文本编辑器(可以通过git config配置)让用户输入提交信息。

5.远程仓库操作命令

  • git remote
    • 用途:用于管理远程仓库的设置,如添加、删除或查看远程仓库的名称和 URL。
    • 用法示例:
      • 查看已配置的远程仓库:git remote -v。它会列出远程仓库的名称和对应的 URL,以及是用于推送(push)还是拉取(fetch)操作。
      • 添加一个新的远程仓库:git remote add [远程仓库名称] [远程仓库URL]。例如,git remote add origin https://github.com/user/repository.git会添加一个名为origin的远程仓库。
      • 删除一个远程仓库:git remote rm [远程仓库名称]。例如,git remote rm origin会删除名为origin的远程仓库。
  • git pushgit pull
    • 用途git push用于将本地仓库的提交推送到远程仓库;git pull用于从远程仓库拉取最新的提交并合并到本地分支。
    • 用法示例:
      • 推送本地分支到远程仓库:git push [远程仓库名称] [本地分支名称]。例如,git push origin master会将本地master分支的提交推送到名为origin的远程仓库。如果本地分支和远程分支名称相同,并且已经设置了上游分支,也可以简单地使用git push
      • 从远程仓库拉取并合并:git pull [远程仓库名称] [本地分支名称]。例如,git pull origin master会从名为origin的远程仓库拉取master分支的最新提交,并合并到本地master分支。在实际使用中,git pull相当于先执行git fetch然后再执行git merge

6.查看历史记录命令

  • git log

    • 用途:用于查看仓库的提交历史,包括提交哈希值、作者、日期、提交信息等。
    • 用法示例:
      • 查看简单的提交历史:git log。它会以逆序(最新的提交在最上面)列出所有提交的基本信息。
      • 查看详细的提交历史,包括文件修改的详细信息:git log -p。这个命令会在每个提交下面列出修改的文件内容,方便查看具体的更改。
      • 以图形化方式查看提交历史:git log --graph。它会以树形图的形式展示提交历史,更直观地显示分支的合并和分叉情况。
  • git reflog

    • 定义:记录的是本地仓库的引用(ref)更新历史。这包括但不限于分支切换、提交、重置等操作。
    • 用途:用于恢复丢失的提交。如果因为某些误操作(如错误地重置了分支或者切换分支后找不到之前的工作),你可以通过git reflog找到之前的提交哈希值,然后使用git checkout或者git cherry - pick等命令恢复丢失的提交。

7.合并相关命令

  • git merge
    • 用途:将一个分支的修改合并到另一个分支。通常用于将特性分支(feature branch)合并到主分支(如mainmaster)。
    • 用法示例:
      • 假设你在feature分支上完成了功能开发,想要合并到main分支。首先切换到main分支,使用git checkout main,然后执行git merge feature。如果合并过程顺利,没有冲突,Git 会自动将feature分支中的提交合并到main分支。如果出现冲突,Git 会暂停合并过程,并提示你手动解决冲突。
image-20241029093543742
  • git rebase

    • 用途:用于将一个分支的提交重新应用到另一个分支的头部,改变提交历史的展示方式。它可以使提交历史更加线性,通常用于在将特性分支合并到主分支之前,整理特性分支的提交历史。
    • 用法示例:
      • 同样假设你在feature - branch上开发,想要将其变基到main分支的最新提交上。首先切换到feature - branch,使用git checkout feature - branch,然后执行git rebase main。在这个过程中,Git 会把feature - branch上的每个提交拿出来,在main分支的最新提交之后重新应用。如果出现冲突,需要像git merge出现冲突时一样手动解决冲突,解决后使用git rebase --continue继续变基操作。

    mergerebase时,要切换到的分支不一样,前者是check outmain,后者是到feature

image-20241029093751476

8.patch相关的命令

git还有个重要的功能就是生成和应用补丁(patch)。所谓patch,就是保存了文件修改内容的一个文件,一些对于大型项目源码可能太多了,可能直接以patch的方式上传到github,比如ST的那个对于他们家传感器的驱动的[项目](STMicroelectronics/st-mems-android-linux-drivers-iio: stm mems iio drivers for Android and Linux platforms.),本身是基于Linux内核的,但是他们的仓库没有上传Linux整个源码,之上传了修改了的文件(不过他们没用.patch文件的形式,而是直接上传了修改了的文件)

生成patch

  • 法1:git diff:用于未提交的修改
1
2
3
4
#只想 patch Test.java 文件
git diff Test.java > test.patch
# 把所有的修改文件打成 patch
git diff > test.patch
  • 法2:git format-patch:用于以提交的修改
1
2
3
4
5
6
$ git format-patch HEAD^       #生成最近的1次commit的patch
$ git format-patch HEAD^^ #生成最近的2次commit的patch
$ git format-patch <r1>..<r2> #生成两个commit间的修改的patch(生成的patch不包含r1. <r1>和<r2>都是具体的commit号)
$ git format-patch -n <r1> #生成最近n个commit的patch
$ git format-patch <r1> #生成某commit以来的修改patch(不包含该commit)
$ git format-patch --root <r1> #生成从根到r1提交的所有patch

应用patch

  • git am:会直接将patch的所有信息打上去,而且不用重新git add和git commit(用于git format-patch生成的patch)

  • git apply:不会将commit message等打上去,打完patch后需要重新git add和git commit(用于git diff生成的patch)