rokevin
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
  • Git

  • 简介
    • 基础命令介绍(与svn的区别)
    • 使用前配置
      • 生成SSH密钥对
      • 配置全局的信息
      • 配置gitignore
    • 工作流程
    • 与远程交互
    • 分支操作
      • 查看分支
      • 创建分支
      • 切换分支
      • 删除分支
    • 常用的撤销操作
  • GitHub 创建项目
    • Command line instructions
    • Git global setup
    • Create a new repository
    • Existing folder
  • 常用命令
    • 测试命令
    • 删除远程分支
    • 删除本地远程分支
    • 添加tag
    • 上传tag
    • 把两段不相干的 分支进行强行合并
  • git rebase和git merge的区别
    • 核心原理与操作效果
      • 1. git merge(合并)
      • 2. git rebase(变基)
    • 关键区别对比
    • 适用场景
    • 注意事项
    • 总结
    • 例子
      • 初始场景
      • 场景 1:使用 git merge 整合代码
      • 场景 2:使用 git rebase 整合代码
      • 核心区别总结
  • 问题
    • git无法pull仓库refusing to merge unrelated histories
    • git中配置autocrlf来正确处理crlf
    • 配置 core.autocrlf
    • GitHub无法访问
    • rebase --force 把本地分支的代码提交到了远程 这时候需要修改怎么办?
      • 场景 1:仅需修改本地最新提交(未推送到远程)
      • 场景 2:需要修改 rebase 后的某个历史提交
      • 场景 3:彻底撤销本次 rebase 操作(恢复到 rebase 前的状态)
      • 关键注意事项
    • log 和 reflog 有什么区别?
      • 核心区别:记录的 “对象” 不同
      • 具体差异与示例
      • 使用场景对比
      • 关键总结
  • 资料

Git

官方网站 | git教程-廖雪峰 | git教程-贝格乐 | git 需要知道的1000个问题

Tag | 分布式

Android忽略文件

简介

基础命令介绍(与svn的区别)

git add          svn add file 往版本库中添加新的文件
git commit       svn commit 将改动的文件提交到版本库
git pull
git push
git status       svn status 查看文件或者目录状态
git diff         svn diff 比较差异
git log          svn log 查看日志
git reset        svn revert (Reset current HEAD to the specified state)(Restore pristine working copy state (undo local changes))
git merge        svn merge 将两个版本之间的差异合并到当前文件
git checkout     svn checkout path(path是服务器上的目录)svn update
                 svn resolved 移除工作副本的目录或文件的“冲突”状态。

使用前配置

生成SSH密钥对

ssh-keygen -t ed25519 -C "your_email@example.com"
  • -t 算法类型 ed25519 指定使用 ed25519 算法,这是目前推荐的安全算法
  • -C 选项用于添加一个注释,通常使用你的在 Git 服务(如 GitHub、GitLab)上注册的邮箱

配置全局的信息

$ git config --global user.name <username>
$ git config --global user.email <mailaddress>

对应仓库的配置可以在仓库根目录.git目录下config文件看到,有关全局配置可以在用户主目录下.gitconfig文件下查看。当然也可以用git config --list命令查看。

配置gitignore

以GitHub给出的node项目为例

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Typescript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env

工作流程

正是因为git的分布式管理,可以随时在没有网络或者网络不方便连接remote的时候,依旧可以控制自己的代码版本等到网络恢复的时候跟别的开发人员同步

与远程交互

git remote add origin http://222.128.102.169:8081/tfs/OWINFO_Projects/Ethor3/_git/newRepo 
git push -u origin --all 

分支操作

默认建立的仓库是没有分支,首次提交会默认创建master分支

通过git branch命令来执行分支操作

查看分支

git branch -a
* master
remotes/aaa/master

创建分支

git branch 名字

切换分支

git checkout 名字

如果远程存在一个分支而本地没有(一般是别人创建了自己需要协同工作),可以在自己当前的分支下git pull拉取最新状态,会看到打印出的日志表示创建了本地分支再进行切换。

不同的分支可以保存不同的工作状态,这样可以比较清晰的将当前开发任务同需要紧急修复bug的工作区分开来

删除分支

git branch -d 名字

常用的撤销操作

$ git commit --amend 撤回最后一次提交并重新提交
$ git reset HEAD~1 撤销上次commit 
$ git reset 撤销已暂存的文件
$ git checkout 撤销当前编辑的内容(恢复至上次保存的状态)

GitHub 创建项目

Command line instructions

Git global setup

git config --global user.name "巴斯"
git config --global user.email "luokw@xxx.cn"

Create a new repository

git clone git@gitlab.hlvan.cn:android/gx-consigner.git
cd gx-consigner
touch README.md
git add README.md
git commit -m "add README"
git push -u origin master

Existing folder

cd existing_folder
git init
git remote add origin git@gitlab.xxx.cn:android/gx-xxx.git
git add .
git commit -m "Initial commit"
git push -u origin master

Existing Git repository

cd existing_repo
git remote add origin git@gitlab.xxx.cn:android/gx-xxx.git
git push -u origin --all
git push -u origin --tags

常用命令

测试命令

ssh -T git@github.com

删除远程分支

git push origin --delete branch_name

删除本地远程分支

一执行 git pull 又回来了

git branch -r -d origin/branch_name

添加tag

git tag -a "tag_name" -m "commit message"

上传tag

git push origin --tags

把两段不相干的 分支进行强行合并

后面加上 --allow-unrelated-histories ,把两段不相干的 分支进行强行合并

git pull origin master --allow-unrelated-histories

git rebase和git merge的区别

二者都是合并代码的命令,区别如下:

  1. git rebase先将本地提交的代码放在一边不管,然后将远程提交的代码合并到本地分支作为新基础代码,最后再将本地提交的代码合并到基础代码上。
  2. git merge将远程提交的代码合并到当前本地提交的代码上。
git rebase origin/master
git merge origin/master

git pull命令默认使用的是merge模式,若使用

git pull --rebase

可将模式改为rebase。

git pull 其实就是 git fetch 和 git merge 的简写。 git pull --rebase 其实就是git fetch 和 git rebase 的简写。

git rebase 和 git merge 是 Git 中用于整合不同分支代码的两种核心命令,但其工作方式、适用场景和最终提交历史有显著区别。以下从原理、效果、适用场景三个维度详细对比:

核心原理与操作效果

假设当前有两个分支:main(主分支)和 feature(开发分支),提交历史如下:

      A---B---C (feature)
     /
D---E---F---G (main)

1. git merge(合并)

  • 原理:创建一个新的合并提交(Merge Commit),将两个分支的修改整合到一起,保留双方的完整提交历史。
  • 操作:在 main 分支执行 git merge feature,结果如下:
      A---B---C (feature)
     /         \
D---E---F---G---H (main)  # H 是新的合并提交
  • 特点:
    • 保留分支的原始提交历史(A、B、C 和 F、G 都存在)。
    • 新增一个合并提交 H,其父提交同时指向 G(main 最后一次提交)和 C(feature 最后一次提交)。
    • 操作简单,无需改写历史。

2. git rebase(变基)

  • 原理:将当前分支的所有提交 “移植” 到目标分支的最新提交之上,改写提交历史,使分支历史呈现线性结构。
  • 操作:在 feature 分支执行 git rebase main,结果如下:
  • plaintext
              A'--B'--C' (feature)
             /
D---E---F---G (main)
  • 特点:
    • 原 feature 分支的提交 A、B、C 被 “复制” 为新的提交 A'、B'、C'(哈希值改变),并接到 main 的最新提交 G 之后。
    • 提交历史变成线性(无合并提交),更简洁。
    • 本质是改写历史,不保留原分支的分叉结构。

关键区别对比

维度git mergegit rebase提交历史保留分支分叉历史,生成合并提交(多线)改写历史为线性,无合并提交(单线)历史可读性完整保留开发过程,但复杂项目可能显杂乱历史清晰简洁,像在目标分支上直接开发冲突处理所有冲突一次性解决(在合并提交时)可能需要多次解决冲突(每个提交移植时可能冲突)历史改写风险不改写历史,安全无风险改写当前分支的提交历史,需谨慎使用适用场景整合公共分支(如 main 合并 feature)优化个人分支或协作分支的历史(如 feature 基于 main 变基)

适用场景

  1. 用 git merge 的场景
  • 整合公共分支:当需要将开发完成的 feature 分支合并到 main 或 develop 等公共分支时,优先用 merge。理由:公共分支需要保留完整的合并记录,方便追溯 “何时整合了哪些功能”,且避免改写公共历史导致团队协作混乱。
  • 快速整合,不关心历史整洁:若项目规模小,或暂时不需要整理历史,merge 操作更简单直接。
  1. 用 git rebase 的场景
  • 优化个人开发分支:在将 feature 分支推送到远程前,通过 rebase main 使分支基于 main 的最新代码,避免合并时产生大量 “无用合并提交”。例:个人开发时,main 有新提交,用 rebase 将自己的 feature 分支 “同步” 到 main 最新状态,保持历史整洁。
  • 协作分支同步:多人间协作同一 feature 分支时,可通过 rebase 同步他人提交,避免频繁生成合并提交。例:同事向 feature 提交了代码,你可以 git pull --rebase 同步,而非 git pull(默认 merge)。
  • 准备合并到公共分支前:在将 feature 合并到 main 前,先用 rebase main 处理冲突,再 merge 到 main,此时 main 会生成一个简洁的合并记录。

注意事项

  1. 不要对公共分支使用 rebase:若 main 等公共分支已被多人使用,rebase 会改写其历史,导致团队其他成员的本地分支与远程不一致,引发混乱。
  2. rebase 冲突处理:变基过程中若遇冲突,需解决后执行 git rebase --continue,而非 commit;若想放弃,执行 git rebase --abort。
  3. 已推送的分支慎用 rebase:若分支已推送到远程,rebase 后需要 git push --force 强制推送(改写远程历史),可能覆盖他人提交,仅建议在个人分支或明确告知团队时使用。

总结

  • git merge:“安全合并”,保留历史但可能杂乱,适合公共分支整合。
  • git rebase:“整洁变基”,改写历史为线性,适合优化个人 / 协作分支,需谨慎使用。

记住核心原则:“变基本地,合并公共”(对本地未推送的分支用 rebase,对公共分支用 merge)

例子

以下通过具体代码提交场景和操作步骤,直观展示 git rebase 和 git merge 的区别。假设我们有一个主分支 main 和一个开发分支 feature,初始提交历史如下:

初始场景

  1. 创建仓库并初始化 main 分支:
# 创建仓库mkdir git-demo && cd git-demo
git init

# 初始化main分支(两次提交)echo "初始化项目" > README.md
git add . && git commit -m "main: 初始化项目"  # 提交Eecho "添加说明" >> README.md
git add . && git commit -m "main: 添加说明"     # 提交F
  1. 创建 feature 分支并开发:
# 从main创建feature分支git checkout -b feature

# 在feature分支提交两次修改echo "功能A" > feature.txt
git add . && git commit -m "feature: 开发功能A"  # 提交Aecho "功能B" >> feature.txt
git add . && git commit -m "feature: 开发功能B"  # 提交B
  1. 此时 main 分支有新提交(模拟并行开发):
git checkout main
echo "修复bug" >> README.md
git add . && git commit -m "main: 修复bug"      # 提交G

当前提交历史(用 git log --graph --oneline 查看):

* 7f3d2b3 (main) main: 修复bug        # G
| * 2e9c5a1 (feature) feature: 开发功能B  # B
| * a1b2c3d feature: 开发功能A           # A
|/  
* 4567890 main: 添加说明                # F
* 1234567 main: 初始化项目              # E

场景 1:使用 git merge 整合代码

目标:将 feature 分支合并到 main 分支。

# 切换到main分支git checkout main

# 合并feature分支git merge feature -m "merge: 整合feature功能"  # 生成合并提交H

合并后提交历史:

*   8h9j0k1 (main) merge: 整合feature功能  # H(新合并提交)
|\  
* | 7f3d2b3 main: 修复bug                  # G
| * 2e9c5a1 (feature) feature: 开发功能B    # B
| * a1b2c3d feature: 开发功能A             # A
|/  
* 4567890 main: 添加说明                  # F
* 1234567 main: 初始化项目                # E

特点:

  • 生成新的合并提交 H,其父亲同时指向 G(main 最新)和 B(feature 最新)。
  • 保留 main 和 feature 的原始提交历史(分叉结构)。

场景 2:使用 git rebase 整合代码

先回退到合并前的状态(模拟重新操作):

# 回退main到合并前(G提交)git reset --hard 7f3d2b3

目标:将 feature 分支基于 main 最新代码变基,再合并到 main。

# 切换到feature分支git checkout feature

# 基于main分支变基(将A、B提交“移植”到G之后)git rebase main

变基后提交历史(feature 分支):

* 2e9c5a1' (feature) feature: 开发功能B  # B'(A、B被复制为新提交)
* a1b2c3d' feature: 开发功能A           # A'
* 7f3d2b3 (main) main: 修复bug          # G
* 4567890 main: 添加说明                # F
* 1234567 main: 初始化项目              # E

再合并到 main 分支(此时无冲突,可快速合并):

git checkout main
git merge feature  # 此时main直接指向B',无新合并提交

最终提交历史:

* 2e9c5a1' (main, feature) feature: 开发功能B  # B'
* a1b2c3d' feature: 开发功能A                 # A'
* 7f3d2b3 main: 修复bug                      # G
* 4567890 main: 添加说明                      # F
* 1234567 main: 初始化项目                    # E

特点:

  • feature 分支的原始提交 A、B 被改写为 A'、B'(哈希值改变),并接到 main 的 G 之后。
  • 提交历史呈线性(无分叉),且 main 合并时无需生成新提交(快进合并)。

核心区别总结

操作提交历史结构提交记录适用场景git merge分叉结构(多线)保留原始提交,新增合并提交公共分支整合(如 main 合并 feature)git rebase线性结构(单线)改写提交历史(复制为新提交)优化个人 / 协作分支历史

通过上述示例可见:merge 更注重 “保留过程”,rebase 更注重 “历史整洁”。实际使用中需根据团队协作规范选择。

问题

git无法pull仓库refusing to merge unrelated histories

https://blog.csdn.net/lindexi_gd/article/details/52554159

git pull --allow-unrelated-histories

git中配置autocrlf来正确处理crlf

遇到这两个错误, 基本上都是叫你将 autocrlf 设置为 false. 但是我觉得这样很不妥。

如果你的源文件中是换行符是LF,而autocrlf=true, 此时git add就会遇到 fatal: LF would be replaced by CRLF 的错误。有两个解决办法:

  1. 将你的源文件中的LF转为CRLF即可【推荐】
  2. 将autocrlf 设置为 false

如果你的源文件中是换行符是CRLF,而autocrlf=input, 此时git add也会遇到 fatal: CRLF would be replaced by LF 的错误。有两个解决办法:

  1. 将你源文件中的CRLF转为LF【推荐】
  2. 将autocrlf 设置为true 或者 false

我的建议:在Mac上设置 autocrlf = input, 在Windows上设置autocrlf = true(默认值)。

这样的话,

Windows:(true)

提交时,将 CRLF 转成 LF 再提交

切出时,自动将LF 转为 CRLF

MAC/Linux: (input)

提交时, 将 CRLF 转成 LF 再提交

切出时,保持LF即可

这样即可保证仓库中永远都是LF. 而且在Windows工作空间都是CRLF, 在Mac/Linux工作空间都是LF.

配置 core.autocrlf

假如你正在Windows上写程序,又或者你正在和其他人合作,他们在Windows上编程,而你却在其他系统上,在这些情况下,你可能会遇到行尾结束符问题。

这是因为Windows使用回车和换行两个字符来结束一行,而Mac和Linux只使用换行一个字符。虽然这是小问题,但它会极大地扰乱跨平台协作。

Git可以在你提交时自动地把行结束符CRLF转换成LF,而在签出代码时把LF转换成CRLF。

用core.autocrlf来打开此项功能,如果是在Windows系统上,把它设置成true,这样当签出代码时,LF会被转换成CRLF:

$ git config --global core.autocrlf true  

Linux或Mac系统使用LF作为行结束符,因此你不想 Git 在签出文件时进行自动的转换;当一个以CRLF为行结束符的文件不小心被引入时你肯定想进行修正,把core.autocrlf设置成input来告诉 Git 在提交时把CRLF转换成LF,签出时不转换:

$ git config --global core.autocrlf input  

这样会在Windows系统上的签出文件中保留CRLF,会在Mac和Linux系统上,包括仓库中保留LF。

如果你是Windows程序员,且正在开发仅运行在Windows上的项目,可以设置false取消此功能,把回车符记录在库中:

$ git config --global core.autocrlf false  

GitHub无法访问

GitHub无法访问、443 Operation timed out的解决办法

  1. 打开 https://github.com.ipaddress.com/ 把IP Address 记录下来
  2. 打开 https://fastly.net.ipaddress.com/github.global.ssl.fastly.net#ipinfo 把IP Address 记录下来
  3. 打开 https://github.com.ipaddress.com/assets-cdn.github.com 把IP Address 记录下来

打开 /etc/hosts

# 第一步中的ip地址
140.82.113.4 github.com 

# 第二步中的ip地址
199.232.69.194 github.global.ssl.fastly.net

# 第三步中的ip地址
185.199.108.153 assets-cdn.github.com
185.199.109.153 assets-cdn.github.com
185.199.110.153 assets-cdn.github.com
185.199.111.153 assets-cdn.github.com

在终端在输以下指令刷新DNS

sudo killall -HUP mDNSResponder;say DNS cache has been flushed

rebase --force 把本地分支的代码提交到了远程 这时候需要修改怎么办?

当使用 git rebase 后用 --force(或 -f)强制推送到远程分支,导致远程历史被改写,此时需要修改的话,需根据具体场景(修改最新提交、修改历史提交、撤销整个 rebase)采取不同策略,核心原则是避免进一步污染远程历史,并确保团队成员同步正确状态。

场景 1:仅需修改本地最新提交(未推送到远程)

如果刚 rebase --force 推送后,发现最后一次提交有错误(如代码写错、提交信息有误),可直接修改后再次强制推送:

操作步骤:

  1. 修改代码:直接在工作区修改错误内容。
  2. ** amend 提交 **:用 --amend 修正最新提交(不会新增提交,而是替换当前最新提交):
git add .  # 暂存修改git commit --amend  # 修正最新提交(可修改提交信息)
  1. 强制推送:由于再次修改了历史(替换了最新提交),需再次强制推送覆盖远程:
git push origin <分支名> --force-with-lease  # 推荐用--force-with-lease,比--force更安全

说明:

  • --force-with-lease 会检查远程分支是否有其他人的新提交,若有则拒绝推送(避免覆盖他人代码),比 --force 更安全,优先使用。

场景 2:需要修改 rebase 后的某个历史提交

如果错误不在最新提交,而是 rebase 后的某个历史提交(如 A' 或 B'),需用 git rebase -i 交互式变基修改历史:

操作步骤:

  1. 找到需要修改的提交位置:用 git log 查看提交历史,记下目标提交的前一个提交哈希(或相对位置,如 HEAD~3 表示倒数第 3 个提交):
git log --oneline  # 示例:假设要修改倒数第2个提交,记为HEAD~2
  1. 启动交互式变基:
git rebase -i HEAD~2  # 编辑倒数2个提交(根据实际情况调整数字)
  1. 标记需要修改的提交:在弹出的编辑器中,将目标提交行的 pick 改为 edit(或 e),保存退出。
# 示例:将第二行的pick改为edit
pick a1b2c3d' feature: 开发功能A  # 目标提交,改为edit
pick 2e9c5a1' feature: 开发功能B
  1. 修改代码并提交:此时 HEAD 会停在目标提交,修改错误后:
git add .git commit --amend  # 修正当前提交
  1. 继续完成变基:
git rebase --continue  # 若中间有冲突,解决后重复add和continue
  1. 强制推送修正后的历史:
git push origin <分支名> --force-with-lease

场景 3:彻底撤销本次 rebase 操作(恢复到 rebase 前的状态)

如果整个 rebase 操作错误(如合并了不该合并的代码),需要完全回退到 rebase --force 之前的状态:

操作步骤:

  1. 找到 rebase 前的本地提交哈希:
    1. 方法 1:用 git reflog 查看本地操作记录(包含每次提交、rebase、reset 等),找到 rebase 前的最后一个提交哈希(如 7f3d2b3):

    2. git reflog  # 找到类似 "checkout: moving from main to feature" 或 "rebase finished" 之前的提交
      
    3. 方法 2:若远程分支在 rebase 前有备份(或他人有同步),可通过远程分支获取历史哈希:

    4. git fetch origin  # 拉取远程最新信息git log origin/<分支名>@{"1 day ago"}  # 查看1天前的远程分支状态(根据实际时间调整)
      
  2. 重置本地分支到目标状态:
git reset --hard <rebase前的哈希>  # 如 git reset --hard 7f3d2b3
  1. 强制推送恢复远程分支:
git push origin <分支名> --force-with-lease

关键注意事项

  1. 通知团队成员:若分支多人协作,rebase --force 后必须立即通知团队其他人,让他们放弃本地旧分支,重新拉取远程最新状态:
# 团队成员操作:git checkout <分支名>git fetch origin
git reset --hard origin/<分支名>  # 强制同步远程最新状态
  1. 否则他人基于旧历史的提交会再次导致冲突。
  2. 避免频繁强制推送:--force 仅建议在个人分支或明确告知团队的情况下使用,公共分支(如 main、develop)严禁使用,否则可能彻底破坏协作历史。
  3. 备份重要历史:操作前可通过 git branch backup-before-rebase 创建分支备份,防止操作失误后无法恢复。

rebase --force 后修改的核心是:通过 --amend 修正最新提交,或 rebase -i 修改历史提交,最后用 --force-with-lease 推送,同时必须同步团队成员更新本地分支。若错误严重,可通过 git reflog 找到历史状态重置恢复。

log 和 reflog 有什么区别?

git log 和 git reflog 都是 Git 中查看提交历史的命令,但二者的核心作用、记录范围和使用场景有本质区别,具体如下:

核心区别:记录的 “对象” 不同

维度git loggit reflog记录对象仓库的提交历史(即 commit 记录)本地仓库的引用变更历史(即 HEAD 和分支指针的移动记录)本质追踪代码的 “版本演变”追踪开发者的 “操作轨迹”(如 commit、rebase、reset、checkout 等)数据范围包含所有提交(本地 + 已推送远程)仅包含本地仓库的操作记录(与远程无关)默认过期时间永久保留(除非手动删除提交)默认保留 90 天(过期未引用的记录会被 Git 垃圾回收)

具体差异与示例

假设进行以下操作:

  1. 初始提交 A → 提交 B → 提交 C(用 git log 可看到 A→B→C)。
  2. 执行 git reset --hard B(回退到 B,此时 git log 只能看到 A→B)。
  3. 执行 git checkout -b feature(创建新分支)。
1. git log:查看提交历史(版本演变)
  • 作用:显示当前分支上所有提交(commit) 的链式历史,按时间倒序排列(最新提交在前)。
  • 示例输出(回退到 B 后):
$ git log --oneline
b7f2d1e (HEAD -> main) B  # 最新提交是B
a1c3e5f A
  • 特点:
    • 只显示 “被分支引用的提交”,回退、删除的提交(如 C)会被隐藏(除非用 git log <被删除的提交哈希> 强制查看)。
    • 包含提交哈希、作者、时间、提交信息等完整提交详情。
    • 常用于追溯代码变更(如 “谁在什么时候改了某行代码”)。
2. git reflog:查看引用变更历史(操作轨迹)
  • 作用:记录本地仓库中 HEAD 指针和所有分支指针的每一次移动(即所有改变引用指向的操作)。
  • 示例输出(上述操作后):
$ git reflog
5e7f9a0 (HEAD -> feature) HEAD@{0}: checkout: moving from main to feature
b7f2d1e (main) HEAD@{1}: reset: moving to B
c8d9e0f HEAD@{2}: commit: C  # 被reset删除的提交C仍有记录
b7f2d1e (main) HEAD@{3}: commit: B
a1c3e5f HEAD@{4}: commit: A
  • 特点:
    • 记录所有操作(包括 commit、reset、rebase、checkout、merge 等),即使提交被删除(如 C)也能找到其哈希。
    • 每条记录包含操作时间(@{n} 表示 “n 次操作前”)、操作类型(如 commit、reset)和关联的提交哈希。
    • 主要用于恢复误操作(如找回被 reset 或 rebase 删掉的提交)。

使用场景对比

场景需求推荐命令原因分析查看代码的提交历史(谁改了什么)git log专注于提交内容和版本演变,包含完整提交信息。找回被 reset/rebase 删除的提交git reflog唯一能记录被丢弃提交的工具,可通过哈希恢复。查看分支创建、切换记录git reflog能追踪 checkout 等分支操作的轨迹。统计贡献者提交次数git log可通过 git log --author="用户名" 筛选。查看远程仓库的提交历史git log配合 git log origin/main 查看远程分支。

关键总结

  • git log 是 “版本日志”:告诉你 “代码有哪些版本”,是提交的 “家谱”。
  • git reflog 是 “操作日志”:告诉你 “你对仓库做了哪些操作”,是你的 “操作备忘录”。
  • 记住:丢了提交找 reflog****,查改了什么找 log。

例如,若误执行 git reset --hard 删掉了最新提交,用 git reflog 找到被删提交的哈希,再用 git reset --hard <哈希> 即可恢复,这是 reflog 最经典的用途。

资料

字节研发设施下的 Git 工作流

http://git-scm.com/ https://subversion.apache.org/ http://tortoisesvn.net/ https://mercurial.selenic.com/ http://www.jason-z.com/smartsvn-solved-ran-out-of-memory/ http://www.smartsvn.com/doc/#menusmartsvn http://www.uml.org.cn/wenzhang/artindex.asp http://www.cnblogs.com/wenhaizhang/archive/2013/05/12/3074906.html http://blog.csdn.net/hustpzb/article/details/8230454/ http://blog.csdn.net/phunxm/article/details/45083335 http://blog.csdn.net/binyao02123202/article/details/20130891 http://www.syntevo.com/smartgit/download?file=smartgit/smartgit-macosx-7_1_2.dmg http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013743256916071d599b3aed534aaab22a0db6c4e07fd0000 http://www.daxiblog.com/2016/01/28/%E7%A8%8B%E5%BA%8F%E5%91%98%E5%BF%85%E5%A4%87%E6%89%8B%E6%9C%BA%E7%AB%AFsvn%E5%92%8C%E4%BB%A3%E7%A0%81%E6%9F%A5%E7%9C%8B%E5%99%A8/ http://blog.csdn.net/wave_1102/article/details/47779401 http://www.syntevo.com/smartgit/download?file=smartgit/smartgit-macosx-7_1_4.dmg http://www.cnblogs.com/huang0925/p/3254243.html http://blog.csdn.net/z1988316/article/details/7547044 https://bitbucket.org/ https://about.gitlab.com/downloads/ http://www.smartsvn.com/doc/ http://www.bootcss.com/p/git-guide/ http://blog.csdn.net/lindexi_gd/article/details/52554159 https://www.zhihu.com/question/29864641 http://blog.csdn.net/black_ox/article/details/17753943 https://help.github.com/articles/generating-ssh-keys/ http://www.cnblogs.com/yepei/p/5650290.html https://www.sourcetreeapp.com/ http://github.phodal.com/ https://about.gitlab.com/installation/#centos-7 https://docs.gitlab.com/omnibus/settings/backups.html http://blog.sina.com.cn/s/blog_458ce8f10102v0rh.html https://git.oschina.net/ http://git.oschina.net/zhoujingjie/apiManager http://git.oschina.net/zhoujingjie/apiManager/tree/master/api?dir=1&filepath=api&oid=6e806ae5fbc14402629cfbc4d440ce8748dfaeb2&sha=e516d0c7c125614e1a6cf0ba9005071b102cfb6a http://api.crap.cn/index.do#/web/article/detail/web/PAGE/WELCOME https://github.com/leanote https://gitee.com/RainyGao/DocSys/releases https://www.liaoxuefeng.com/wiki/896043488029600 https://www.cnblogs.com/grs9505/p/11439364.html https://www.cnblogs.com/ludashi/p/8213550.html https://www.cnblogs.com/mouseleo/p/11918015.html https://blog.csdn.net/nobody_1/article/details/88828638 https://www.cnblogs.com/fanyong/p/4905951.html https://blog.csdn.net/Al_assad/article/details/81145856?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control https://www.cnblogs.com/frankltf/p/11631481.html https://blog.csdn.net/syrchina/article/details/88392039 https://www.cnblogs.com/L-shuai/p/15814859.html https://www.jianshu.com/p/2d3679cb59ec https://blog.csdn.net/qq_42156063/article/details/121334050 https://blog.csdn.net/mutouren_abc/article/details/124680591 https://blog.csdn.net/lwc5411117/article/details/103391341 https://blog.csdn.net/qq_40395874/article/details/119537527 https://blog.csdn.net/mandagod/article/details/115633164 https://www.zhihu.com/search?q=Clearcase%20%E5%92%8C%20git&type=content

最近更新:: 2025/10/26 22:30
Contributors: luokaiwen, 罗凯文