git stash
缓存区:只会存储已跟踪文件
1. Git 基础概念
-
版本控制:Git 是一种分布式版本控制系统,用来追踪文件的变化,并支持多人协作。每个人的工作副本都是完整的仓库,历史记录可以在本地访问,不依赖中央服务器。
-
提交(Commit) :Git 记录的单位,每次提交代表一个快照。每个提交都会被分配一个唯一的 SHA-1 哈希值。
-
分支(Branch) :分支是 Git 用来并行开发的工具。主分支通常叫
master或main,但可以根据需求创建不同的分支。 -
合并(Merge) :将两个分支的内容合并到一个分支。Git 会尽可能自动解决冲突,但有时需要手动解决。
-
工作区、暂存区和版本库:
- 工作区:当前目录的文件,尚未被 Git 跟踪或已经修改但未提交的文件。
- 暂存区(Staging Area) :也称为索引区,Git 会将修改的文件加入暂存区,准备提交。
- 版本库(Repository) :保存所有历史提交记录的地方。
易错点:
- 提交到暂存区与提交到仓库:很多初学者会误解
git add和git commit的区别。git add是将文件修改放入暂存区,而git commit才是把修改保存到 Git 版本库。 - 提交前不检查文件状态:很多人直接
git commit,没有git status查看文件状态,容易忽略未添加到暂存区的文件。
2. Git 工作流
-
克隆仓库(Clone) :从远程仓库复制一份本地仓库。
git clone <repo_url> -
拉取(Pull) :将远程仓库的更新拉到本地,
git pull等同于git fetch+git merge。git pull origin master -
推送(Push) :将本地的提交推送到远程仓库。
git push origin <branch_name> -
创建分支(Branch) :
git branch <branch_name> # 创建本地分支 git checkout <branch_name> # 切换到指定分支 git checkout -b <branch_name> # 创建并切换到新分支 -
合并分支(Merge) :
git checkout <target_branch> # 切换到目标分支 git merge <source_branch> # 将源分支合并到目标分支注意:如果合并时出现冲突,Git 会标记冲突文件,你需要手动解决冲突,然后再提交。
易错点:
- 合并冲突未解决:合并时如果出现冲突,很多人容易忘记解决冲突后提交。解决冲突后必须
git add文件,并执行git commit来记录合并。
3. Git 常用命令
-
查看状态(Status) :
git status # 查看当前工作区和暂存区的文件状态 -
修改最后一次提交信息
git commit --amend然后输入
i进入编辑模式,编辑完成,esc&:wq& success -
查看历史记录(Log) :
git log # 查看提交记录 git log --oneline # 简洁版日志 git log --graph # 显示提交历史图形 -
撤销修改(Checkout) :
git checkout <file> # 撤销暂存区的文件 git checkout -- <file> # 撤销工作区的文件 -
删除文件(Remove) :
git rm <file> # 删除文件并将删除操作加入暂存区 git rm --cached <file> # 从暂存区移除文件(保留本地文件) -
查看差异(Diff) :
git diff # 查看工作区和暂存区之间的差异 git diff --staged # 查看暂存区和最新提交之间的差异
易错点:
- 误删文件:删除文件后,如果不小心提交了删除操作,可以使用
git checkout -- <file>恢复删除的文件。
4. Git 远程操作
-
添加远程仓库(Remote) :
git remote add origin <repo_url> # 添加远程仓库 git remote -v # 查看远程仓库列表 -
拉取远程仓库更新(Pull) :
git pull origin <branch_name> -
推送到远程仓库(Push) :
git push origin <branch_name> -
删除远程分支:
git push origin --delete <branch_name>
易错点:
- 远程仓库分支名不一致:如果本地和远程仓库的分支名不一致,推送时会失败,建议使用
git push --set-upstream origin <branch_name>来指定远程分支名。
5. Git 分支管理
-
查看本地和远程分支:
git branch # 查看本地分支 git branch -r # 查看远程分支 git branch -a # 查看所有分支 -
删除本地分支:
git branch -d <branch_name> # 删除本地分支 git branch -D <branch_name> # 强制删除本地分支 -
切换分支时的注意事项: 如果当前分支有未提交的修改,切换到另一个分支时 Git 会提示你先提交或暂存修改,或者通过
git stash暂时保存修改。
易错点:
- 删除未合并的分支:在删除分支之前需要确认该分支的修改是否已合并到主分支或其他重要分支,避免丢失代码。
6. Git 标签(Tag)
-
创建标签:
git tag <tag_name> # 创建轻量标签 git tag -a <tag_name> -m "message" # 创建附注标签 -
查看标签:
git tag # 查看所有标签 git show <tag_name> # 查看标签的详细信息 -
推送标签到远程:
git push origin <tag_name> # 推送单个标签 git push origin --tags # 推送所有标签 -
删除标签:
git tag -d <tag_name> # 删除本地标签 git push origin --delete <tag_name> # 删除远程标签
易错点:
- 未推送标签:创建标签后,不自动推送到远程仓库,很多人忘记推送标签,导致远程无法同步标签。
7. Git 的协作和冲突解决
-
如何处理合并冲突:
- Git 会在冲突文件中插入标记,类似
<<<<<<<,=======,>>>>>>>,表示冲突的不同版本。 - 解决冲突后,保存文件并使用
git add <file>将解决后的文件添加到暂存区。 - 使用
git commit完成合并。
- Git 会在冲突文件中插入标记,类似
-
Rebase 与 Merge 的区别:
- Merge 会创建一个新的合并提交,将两个分支合并。
- Rebase 会将当前分支的提交移动到目标分支的最新提交之上,历史记录更线性,适合保持整洁。
易错点:
- 误用 rebase:Rebase 是修改历史,会改变提交的哈希值,不建议在已公开的分支(如
main)上使用 rebase,因为这会导致其他开发者的提交历史混乱。
8. git reset 命令详解
git reset 用于撤销本地的某些修改或提交,并可以调整 HEAD、暂存区或工作区的状态。
基本用法:
git reset <commit>
commit可以是提交的哈希值、分支名、HEAD^(上一个提交)等。
常用选项:
-
--soft:仅仅修改 HEAD,暂存区和工作区不受影响。git reset --soft <commit>- 这个选项用于撤销提交,并将改动保留在暂存区,允许你重新提交。
-
--mixed(默认) :修改 HEAD 和暂存区,工作区不受影响。git reset --mixed <commit>- 会将指定提交之后的更改移出暂存区,但保留在工作区。通常用于撤销已经添加到暂存区但还未提交的更改。
-
--hard:修改 HEAD、暂存区和工作区。git reset --hard <commit>- 会完全撤销指定提交之后的所有更改,包括工作区和暂存区的文件,通常用于丢弃未提交的本地修改。
使用场景:
git reset --soft:用于合并多个提交(将多个提交合并为一个新的提交)。git reset --hard:用来丢弃某些本地修改,例如清理未提交的代码或回退到上一个稳定版本。
易错点:
--hard重置不可恢复:git reset --hard会丢失工作区的修改,且无法恢复。执行前需谨慎,确保没有未保存的重要更改。--soft与--mixed的区别:--soft会将修改保留在暂存区,而--mixed会将修改移出暂存区但保留在工作区。
9.git rebase 命令详解
变基git rebase 用于将当前分支的修改移动到目标分支的顶部,能够帮助整理和优化提交历史,避免合并提交。
删除不需要的一些提交记录;使得分支提交记录更干净;但是提交的内容依然存在的;
一些常见的参数:
- p: pick
- R: reword
- E: edit
- S: squash
- F: fixup rm -fr ".git/rebase-merge" 本地移除命令
合并提交之后,后一个会覆盖前一个的提交信息,体现了他的作用;
基本用法:
git rebase <branch>
branch是目标分支,当前分支的提交将被“搬移”到目标分支的顶部。
常用选项:
-
--interactive(或-i) :交互式 rebase,允许用户编辑、重排、合并、删除提交。git rebase -i <commit> -
用途:修改提交历史,比如合并多个提交(squash)、修改提交信息、删除某些提交等。
-
--onto:用于指定一个不同的目标分支,适用于复杂的 rebase 操作。git rebase --onto <newbase> <upstream> <branch> -
例如,你有一个从
master上创建的分支feature,你可以将feature分支的提交移动到newbase分支的顶部。
使用场景:
- 整理提交历史:当多个开发者在不同分支上提交工作时,通过
rebase可以使提交历史更整洁、线性,避免多余的合并提交。 - 解决分支冲突:如果你基于一个分支做开发,期间目标分支有新的提交,使用
rebase可以将目标分支的提交合并到你当前分支的顶部。
cherry pick
git cherry-pick 用于将某个特定提交从一个分支应用到当前分支,它不会合并整个分支的历史,而是单独引入一个提交。
将一个分支中提交的一条记录合并到其他分支去; eg: 在dev分支修复了一个bug,提交到了远程分支,在这条分支之前还存在其他提交,这时候就可以切换到主分支;找到这条提交记录id,将这个bug提交commit到主分支上线;
基本用法:
git cherry-pick <commit>
commit是要被“挑选”的提交的哈希值。
常用选项:
-
--edit:允许编辑挑选的提交信息,默认为自动使用原提交信息。git cherry-pick --edit <commit> -
--abort:如果在 cherry-pick 过程中遇到冲突,可以用--abort来中止操作并恢复到操作前的状态。git cherry-pick --abort -
--continue:解决冲突后,继续进行 cherry-pick 操作。git cherry-pick --continue -
--no-commit:应用提交的更改,但不立即创建提交。这允许你在应用更改后先进行修改,然后再提交。git cherry-pick --no-commit <commit>
使用场景:
- 挑选特定提交:当你只想从某个分支挑选特定的提交,而不是合并整个分支时,
cherry-pick非常有用。例如,某个 bug 修复只在feature分支上,而你想将它应用到master分支。 - 修复错误:如果一个提交在开发过程中修复了一个问题,而你需要将这个提交移植到其他分支时,可以使用
git cherry-pick。
git bisect
二分查找某次提交
git bisect start HEAD 重点哈希字符串 ( HEAD:起点 第二个: 终点 )
git bisect bad 坏的提交
git bisect good 是一个好的提交
git bisect reset 退出
仓库克隆
- 先创建一个空白的项目
- 导入方法
- 通过命令:
git remote add gitlab(仓库名) git@git.xxx.xxxx.git(仓库地址) - 在仓库直接选择导入
- 通过命令:
移除提交缓存
场景: 比如初始化仓库的时候,没有添加.gitignore文件,导致node_modules文件也被git管理,这时可以通过以下步骤恢复;
git rm --cached -r .git add .git commit -m "init"
gitignore
vscode可以安装gitignore插件,然后ctrl+p >add gitignore
如果将敏感数据提交了怎么办? 如何从历史记录里移除?
1. 立即从最新提交中移除敏感数据
如果你已经将敏感数据提交并推送到远程仓库,但还没有被其他人拉取或克隆(即仓库尚未广泛传播),可以考虑在最新提交中将敏感数据删除。
步骤:
-
从工作区删除敏感数据:
git rm <path_to_sensitive_file> git commit -m "Remove sensitive data" -
推送更改到远程仓库:
git push origin <branch_name>这样做会从当前提交中移除文件,但文件仍然会存在于历史记录中。
2. 完全从历史记录中移除敏感数据
如果敏感数据已经提交到 Git 历史中(例如,代码已经推送到远程仓库并被其他人拉取),你需要彻底从历史记录中删除这些敏感数据。这可以通过 git filter-branch 或 git filter-repo(推荐)来实现。