# Git使用

# 0、创建版本库

git init, 可以初始化本地仓库

本地仓库和远程库关联 git remote add origin <remote-url>

git clone <repository_url>, 从远程克隆仓库到本地,分支是远程的默认分支。 如果想克隆指定分支,可以使用 git clone -b <branch_name> <repository_url>

工作区: 当前工作的文件夹 working directionary

# 0.5、工作区、暂存区 Stage

工作区就是我们的文件夹目录。.git文件夹可以看做是我们的版本库。版本库由暂存区和分支等组成。

git add把文件添加进去,实际上就是把文件修改添加到暂存区;

git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。

# 1、配置用户

# 1.1 配置全局用户

# 配置全局用户
git config --global user.name "xdyuan"
git config --global user.email "xdyuan@gmail.com"
git config -l 查看配置项

# 1.1 配置本地用户

如果不想配置全局用户,只想配置某一个repo下的。进到这个repo的目录下然后配置当前repo的用户

git config user.name "xdyuan"
git config user.email "xdyuan@gmail.com"

# 2、git add 添加文件到版本库

git add 添加新的文件到暂存区

git add -u 仅添加已经被add的文件(即tracked file) 不会提交新建文件(untracked file)

git add . 添加所有的文件到版本库

git status 查看版本库的状态

git diff 查看文件修改前后的区别

git diff HEAD -- README.md 查看某个文件的区别

Reset 之后往往本地的版本会落后远端的版本, 这时候如果需要推送就得借助git push -f 也就是fast-forwards 强制合并

# 2.5 修改和撤销 restore

Git restore 是一个用于恢复或撤销文件更改的命令。这个命令可以帮助开发者在多种情况下管理文件的状态,例如还原文件到最新提交的状态、丢弃未暂存的更改、丢弃已暂存但未提交的更改等。

命令使用示例

还原文件到最新提交的状态: 如果你想要撤销对某个文件的所有未提交更改,可以使用以下命令: git restore file 这将会将指定文件 file 恢复到最新的提交状态。

还原文件到暂存区的状态: 如果文件已经被添加到暂存区,但你希望撤销这些更改,可以使用: git restore --staged file 这个命令将文件 file 恢复到暂存区的状态,但不会影响工作目录中的文件。

还原全部更改: 要还原所有未提交的更改,包括工作目录和暂存区的更改,可以使用: git restore . 使用这个命令需要谨慎,因为它会清除所有未提交的修改。

还原文件到指定提交的状态: 如果你想将文件 file 恢复到特定提交 commit 的状态,可以使用: git restore --source=commit_id file 这个命令在需要查看历史状态或将文件还原到历史版本时非常有用。

交互式还原: 以下命令允许你以交互方式选择要还原或保留的更改: git restore -i 执行这个命令会打开一个交互式界面,让你选择如何处理每个更改。

git restore 的目标是提供一种更直观、易于理解的方式来管理文件的状态。它的引入使得 Git 用户能够更容易地处理不同阶段的更改,从而提高了工作流的效率。需要注意的是,git restore 是 Git 2.23 版本引入的一个命令,如果你使用的是较早版本的 Git,可能无法使用 git restore 命令,但你仍然可以使用 git checkout 等命令来进行类似的操作。

与其他命令的对比

git restoregit reset 的区别在于,git restore 更多地用于操作工作区和暂存区的内容,而 git reset 通常用于重置提交点。git restoregit checkout 的区别在于,git restore 提供了更细粒度的控制,允许你只操作工作区或暂存区,而 git checkout 通常用于切换分支或还原文件内容。

# 3、设定默认远程push分支

设定默认远程push分支

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

git branch -u origin/dev 和上面是一个意思

现在随便修改一下工程文件的内容,然后git commit ,git push,之后就可以直接提交到远程的dev分支中,而不会是master

git branch --unset-upstream master 撤销本地与远程分支的映射关系

git branch -m main

设定默认push分支

git push --set-upstream origin master

git push -u origin master 和上面的一样效果,第一次push时使用-u参数关联本地master分支和远程master分支,后续可以简化命令

git push origin dev 把本地的dev分支推送到远程 如果远程已经存在dev分支,但是本地还没有,可以使用git checkout -b dev origin/dev. 基于远程分支dev创建本地分支dev。后续拉取代码就可以使用git pull origin dev。推送就用git push origin dev

# 4、编辑commit提交内容

git commit -m "message". 提交修改

git commit --amend 编辑最近一次的提交日志

编辑某一次的commit提交日志,需要使用rebase 命令。

# 1、比如想修改最近三次提交中的某一次提交信息
git rebase -i HEAD~3

# 2、此时会给你一个交互的信息, 你可以按a或者i来编辑

pick 367d676 2nd submit,new submit
pick 3a0fb46 3rd submit by xdyuan
pick 0021c7d 第四次提交-变基来修改commit msg

# Rebase 3f9fcd7..0021c7d onto 3f9fcd7 (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# x, exec <command> = run command (the rest of the line) using shell

# 如果你想修改 3a0fb46 这一次提交的信息.这里我们用r就行,没必要用e。
# 把 pick 3a0fb46 3rd submit by xdyuan 改成 r 3a0fb46 3rd submit by xdyuan
# 然后按esc之后再输入:wq。然后回车编辑你的新信息之后.继续按esc之后再输入:wq回车,就完成了

# 4.5 reset 回退

git reset --hard HEAD^ 回退到上一个版本 , HEAD^^表示前2个版本,前100个版本可以写成HEAD~100。这是强制回退,文件都会被修改

git reset --soft HEAD~1 回退到上一个版本,会删除commit记录, 相比hard不会重置文件内容,可以修改后再次提交

git reset --hard commit_id 可以回到对应提交id的版本

--mixed会回退到上个版本已添加但未提交的状态。而--soft会回退到上个版本的未提交状态

reset 之后git log 可能就看不到日志了,需要使用git reflog。此时可以找到被reset掉的reseted_commit_id。使用这个id再次使用reset还原git reset --hard reseted_commit_id

# 5、关于日志

git log 查看日期

git log --pretty=oneline 查看格式化的单行日志

git log --pretty=format:%s 查看格式化的commit日志

git log --graph --pretty=oneline --abbrev-commit 查看分支合并情况

git reflog 查看命令历史,记录了所有的命令

git commit --amend 编辑最近一次的提交日志

查看某个文件夹的提交历史 git log -- /folder

# 6、checkout

git checkout -- <file> 撤销修改, 回到上一次add或者commit时的状态。修改了文件但是还没有提交, 这时候不想要了,丢弃的话可以使用这个

git checkout -b dev origin/dev 基于远程dev分支创建本地dev分支

git reset HEAD <file>撤销暂存区的修改, 回到add之前。文件内容不会发生变化

# 7、rm 删除 和 恢复

git rm test.txt 删除文件, 之后可以直接commit提交删除操作

恢复删除的文件 不小心从本地删除文件 git checkout -- file_name 可以重新恢复

# 8、远程仓库

# 关联远程仓库

现有本地库,再创建远程库,此时创建的远程库最好是空的

git remote add origin <remote_repo_url> 添加远程库

git remote remove origin 取消关联远程仓库

git remote -v 查看自己的权限

git push -u origin master 推送本地仓库到远程库,

把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。

由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送到远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。

以后做了修改就可以 git push origin master 把本地master分支的最新修改推送到origin远程仓库

# 克隆远程仓库

先创建远程库, 直接克隆到本地,就不需要再本地再新建了

git clone <remote-url>

# 9、分支相关

git branch -a 查看所有分支

git branch dev 创建dev分支

git checkout dev 切换为dev分支

git branch 查看当前分支和其余分支

git branch -d dev 删除dev分支

git branch -a 查看所有分支

git branch -D feature-vulcan feature-vulcan分支如果还没有被合并,如果删除,将丢失掉修改,如果要强行删除,需要使用大写的-D参数。

# 9.5 切换分支

以前的方式,切换已存在的分支git checkout <branch-name>

新建分支并切换 git checkout -b <new-branch-name>

新的方式,switch ,命令

创建并切换到新的dev分支,可以使用:git switch -c dev

切换到已存在的dev分支,git switch dev

# 10、Stash

git stash 存储工作现场, 等以后恢复现场后继续工作: 这个主要用于当有临时bug需要修复,但是当前工作未完成, 需要先修bug, 但是不提交

git stash list 存储列表

git stash pop 恢复工作现场

git stash apply stash@{0} 应用某个stash,但是不删除

git stash drop stash@{0} 删除stash

# 11、tag标签

git tag <tagname> 创建一个标签, 默认是当前最新的commit,一般 git tag <tagname> <commit-id> 也可以指定一个以前的commit 打tag

git tag -a <tagname> -m “desc” 可以给这个标签加说明文字

git tag 查看所有的标签

git show <tagname> 可以查看这个标签的详情

git tag -d <tagname>删除标签

git push origin <tagname> 推送标签到远程

git push origin —tags 推送所有的标签到远程

refusing to merge unrelated histories

git pull origin master --allow-unrelated-histories

给分支添加备注

npm i -g git-br

git config branch.分支名称.description 杭州安全通开发分支

Git br 查看分支描述

# 12、关于合并

# 12.1 只合并文件的改动,不合并提交commit记录

注意下面只是简单的文件拷贝,不会合并

# 先切换到想要合并到的分支,可以用 git checkout target-branch
git checkout source-branch -- .

这将会把source-branch分支上的所有变更(但不包括commit)应用到当前的target-branch分支上,需要创建一个新的commit来记录这次变更。

如果只想把某个文件拷贝过来。

git checkout dev4 src/1.js

如果想把某个文件下的文件变动拷贝过来

git checkout dev4 src/*

# 12.2 git merge fast-forward 快进合并

git merge dev 

合并指定分支(dev) 到当前分支, 使用fast forward模式, 也叫做快进合并

'快进合并是指在合并操作中,如果当前分支的历史完全包含在目标分支的历史中,Git 可以直接将当前分支指向目标分支的最新提交,而无需生成额外的合并提交。换句话说,Git 在这种情况下无需创建新提交来表示“合并”操作。'

简单来说,快进合并意味着目标分支已经是当前分支的“延续”。

示例场景

假如我们有一个repo的main分支,最初历史如下

A -- B -- C(main)

然后我们新建一个名为feature的分支,并在这个分支上进行了两次提交

A -- B -- C(main)
           \
             D -- E (feature)

如果在main分支没有额外的提交,现在你想要将feature分支合并回main分支,在这种情况下,main分支的提交历史完全是feature分支提交历史的子集。因此我们可以使用快进合并,只需要将main分支的指针指向feature

A -- B -- C -- D -- E (mian, feature)

使用如下的命令

git checkout main
git merge feature

这种情况不会产生额外的合并提交,只移动main分支的指针到feature最新提交E。合并后的历史是线性的,简化了项目的历史记录。

如果不想快进合并,仍然想保留分支历史, 可以使用 --no-ff 。

# 12.3 非快进合并

git merge --no-ff -m "merge with no-ff" dev 不适用fast forward模式合并分支, 此种方法会保留分支记录

非快进合并示例

假如我们有一个repo的main分支,最初历史如下

# main
A -- B -- C(main)

#feature
A -- B -- C(main)
           \
            D -- E (feature)

如果main分支也进行了新的提交F


A -- B -- C -- F(main)
					 \
					  D -- E (feature)

在这种情况下,git无法进行快进合并,会创建一个新的合并提交记录

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

# 12.4 cherry-pick 只合并某一个分支的某一次commit到当前分支

1、‌使用git cherry-pick命令来选择并应用该commit‌: 一旦你有了commit的哈希值,就可以使用git cherry-pick命令来应用它。例如,如果你的commit哈希值是abc1234,你可以运行:

git cherry-pick abc1234

这条命令会将指定的commit应用到当前分支上。

2、‌**解决冲突(如果有的话)**‌: 如果合并过程中出现了冲突,Git会暂停cherry-pick操作,并让你解决冲突。你需要手动编辑冲突的文件,解决冲突后,使用以下命令继续cherry-pick操作:

git add <resolved-file>
git cherry-pick --continue

如果你决定放弃这次cherry-pick操作,可以使用:

cherry-pick --abort

# 13、抓取和拉取

‌**git抓取(fetch)和git拉取(pull)的主要区别在于它们对远程仓库数据的处理方式和适用场景不同。**‌‌

# 行为差异

  • git fetch‌:从远程仓库获取最新的提交和分支信息,但不会自动将这些更改合并到当前分支。远程分支(如origin/main)会更新,但本地分支(如main)保持不变。
  • git pull‌:相当于git fetch和git merge的组合,从远程仓库获取最新的提交和分支信息,并立即将这些更改合并到当前分支。这意味着本地分支会自动更新为与远程分支同步的状态。

# 适用场景

  • git fetch‌:适用于想要先了解远程仓库的最新状态,再决定如何处理更新的情况。对更改合并有更精确的控制,适合在多人协作项目中使用。
  • git pull‌:适用于确定需要立即将远程更改同步到本地分支的情况。对合并行为无需过多控制,适合在单人项目中使用更为方便。

# 具体操作示例

  • git fetch‌:例如,git fetch origin main 会从远程仓库获取最新的提交和分支信息,但不会自动合并到当前分支。
  • git pull‌:例如,git pull origin main 会从远程仓库获取最新的提交和分支信息,并立即将这些更改合并到当前分支。

# git revert

git revert 用于反做某一个版本, 比如commit 了 三次, 但是第二次不想要了, 但是保留第三次的提交。 就需要用到revert

git revert -n commit_id 反做这个id的commit。可能会出现冲突 需要手动解决,然后重新commit 一次即可。 注意此时的commit message 最好写成如下格式

Revert "feat(txt): add txt"

This reverts commit 6788a3c72b6bae5a9780503ea69681da18f44c3e.

# git rebase

Rebase 可以对某一段线性提交历史进行编辑、删除、复制、粘贴, 合理使用rebase可以使得我们的提交历史干净简洁

1、合并多个commit为一个完整的commit

​ git rebase -i ( startpoint endpoint ] 前开后闭

​ git rebase -i HEAD~2 2表示要合并的数量

弹出之后的

2、将某一段commit粘贴到另一个分支上

​ git rebase -i ( startpoint endpoint ] —onto [branchName]

​ --onto的意思是要将该指定的提交复制到哪个分支上, 此时的HEAD 是有问题的, 一般需要

​ git checkout branchName

​ git reset --hard last_commit

# Fork之后如何拉取代码提交PR

此种情况适用于本地clone的是fork后的仓库,然后需要拉取原仓库,同时提交自己的代码到原仓库,可以提交PR,PR可以邀请人来审核之后merge

  1. 本地添加原仓库的地址

    git remote add upstream <原仓库git地址>
    
  2. 获取原仓库指定分支的更新

    git fetch upstream main
    
  3. 合并原仓库的指定分支代码到本地的分支

    git merge upstream/main  
    git merge upstream/main  origin/dev
    
  4. 有冲突的话需要合并

  5. 修改代码合并之后提交到本地仓库

    git add .
    git commit -m "some change"
    
  6. 推送提交到自己fork的仓库

    git push orimain dev
    
  7. 这时候可以到gitlab或者github提交PR。等待审核人合并PR即可

上次更新: 4/1/2025, 9:33:10 AM