廖雪峰教程
w3school教程
以上是git比较有名的两个教程网站,一下文章基于上面两个网站
前言:git命令格式
git <command> [options] [arguments]
这里的组成部分意味着:
<command>:是你想要执行的 Git 操作,如 clone、commit、push、pull 等。
[options]:(可选)是可以修改命令行为的选项。这些选项一般以单破折号 – 开头(对于短选项)或双破折号 — 开头(对于长选项)。例如,git log –oneline 中的 –oneline 是一个选项,用于以简洁的单行格式显示提交历史。
[arguments]:(可选)是传递给命令的其他参数,这些参数的含义会根据具体的命令而变化。例如,在 git clone https://example.com/some-repo.git 中,https://example.com/some-repo.git 是一个参数,指定了要克隆的仓库的 URL。
一,工作区域
Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。
在 Git 中,有三个主要的工作区域,它们是:工作树(或工作目录)、暂存区(或索引)、和版本库。这三个区域协同工作,使得 Git 能够有效地跟踪和管理项目版本。下面是对这三个区域的简要介绍:
1.工作树(Working Tree 或 Working Directory)
就是你在电脑里能看到的目录,比如我的learngit
文件夹就是一个工作区,通常来说工作区是除了.git之外的集合
2.暂存区(Staging Area 或 Index)
存在于.git文件夹下,暂存区是一个准备好的下一次提交的更改列表。使用 git add 命令将这些更改添加到暂存区。暂存区提供了一个灵活的方式来控制你希望包含在下一次提交中的更改。你可以选择性地添加更改到暂存区,以便在提交时只提交部分更改而不是所有当前工作目录中的更改
3.版本库(Repository)
存在于.git文件夹下,版本库是 Git 用来保存项目的元数据和对象数据库的地方。执行 git commit 命令时,暂存区的内容就会被提交到版本库。版本库包含了你的项目的所有提交历史,以及指向这些提交记录的头指针(如分支和标签)。每次提交都是工作目录在某一时刻的快照
把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add
把文件添加进去,实际上就是把工作区文件修改添加到暂存区;
第二步是用git commit
提交更改,实际上就是把暂存区的所有内容提交到版本库。
HEAD 当前分支指针
二,帮助命令
①git help <command>
②git help help
如果要查看某条命令的具体帮助可以用第一条
第二个是针对帮助本身的帮助
三,版本回退
git种可以版本回退的命令是reset,以及revert
1.reset
其原理是移动HEAD指针,命令格式如下
git reset [--hard|--soft|--mixed(缺省默认)] [HEAD(缺省默认当前)|HEAD~N|HEAD^]
常用模式又3种:3种模式下HEAD都会移动到相应的commit下,不同的是对暂存区和工作区的改动
–soft | –mixed(缺省默认) | –hard | |
工作区 | 不会受到影响 | 不会受到影响 | 移动到commit |
工作区修改 | 不会受到影响 | 不会受到影响 | 删除丢弃 |
暂存区 | 将当前commit到目标commit 的修改叠加进暂存区 |
清空 | 清空 |
使用场景 | 如果你刚刚完成了一次提交,然后意识到你忘记了暂存某些更改或者消息写错了,你可以使用git reset –soft HEAD~回退到上一次的提交,并重新暂存和提交,或者你可以HEAD~N将多个提交合并 | 当你想重置暂存区到某个特定的提交同时保留对文件的更改(未暂存状态)时,你可以使用git reset –mixed或者简单地 git reset。接下来你可以重新审查和暂存这些更改。 | 如果你的代码库处于混乱状态,你想完全放弃自上次提交后所做的所有更改,可以使用git reset –hard HEAD。还要注意,这会删除所有未提交的更改,因此必须谨慎使用。 |
可以发现–hard可以造成修改的丢失
HEAD=HEAD~0 当前位置,如果是 git reset –hard HEAD 表示删除当前commit前的更改,注意这会造成修改的丢失
HEAD^=HEAD~1 HEAD^^=HEAD~2
2.revert
命令格式如下
git revert HEAD
回退到前一个commit,这个和reset区别是重新提交了一个commit,HEAD往前走了一步,而git reset –hard HEAD^ 是往后走了一步
四,分支
1.HEAD,分支,commit提交三者的关系
Git里,HEAD严格来说不是指向提交,而是指向master(分支),分支才是指向提交的,HEAD指向的就是当前分支.HEAD、分支和提交(commit)之间存在着紧密的关系,它们共同协作以管理和追踪代码的历史记录。下面是这三者之间关系的解释:
提交(Commit)
代表仓库中的一个特定状态。每个提交都包含了代码在特定时间点的快照,以及一些元数据,如作者信息、提交信息和一个或多个父提交的引用;每个提交都有一个唯一的SHA-1哈希值 ID
分支(Branch)
是指向某个提交的引用,它代表了代码的一个独立线路。分支是一个可移动的指针,当新的提交加入到分支时,分支指针会自动向前移动指向最新的提交。
在 Git 中创建分支是非常轻量级的,因为它只是简单地创建了一个新的指针。你可以随时创建、删除和移动分支(其实就是指针的移动),而不会影响仓库中的实际文件内容
HEAD
指向当前你所在的分支的最新提交。当你切换分支时,HEAD 会更新以指向新分支的最新提交,通常它指向一个分支名,这意味着你在这个分支上的任何新提交都会使 HEAD 随之移动
它们之间的关系
当你在一个分支上进行工作并创建一个新的提交时,这个提交会成为该分支的最新提交。分支指针会自动前进以指向这个新的提交;HEAD 指针通常指向当前分支(比如 master
或 feature
分支),表示你正在这个分支上工作。当你在这个分支上创建新提交时,HEAD 会随着分支指针一起移动到新提交;当你切换分支时(比如使用 git checkout branchname
),HEAD 更新以指向新分支的最新提交。此时,你的工作目录和暂存区会被更新以反映这个新分支的内容
2.相关命令
//查看分支 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>
注意①:切换分支的时候工作区没有修改,暂存区没有暂存
五,git中版本A,版本B实现方式
为不同公司定制的两个版本肯定会有明显的差异,直接使用 git merge 并不是最好的解决方案,因为它会将一个分支的所有更改合并到另一个分支中,这样可能会引入不必要的代码改动。我们可以采用其他的方法来同时维护两个版本的项目,并对两者进行必要的同步。以下是几种可以考虑的策略
1.git cherry-pick
git cherry-pick <commit-hash> //后面跟的commit 就是你想从任何其他分支的修改记录值
注意先后顺序,假如你想合并多个commit,必须按照他们的产生时间一次添加;
2.git format-patch => git am
git format-patch g <start-commit>..<end-commit> //产生patch文件,注意不包括start-commit git am <patch-file1> <patch-file2> .... //将上面产生的补丁包 添加到当前分支中,并产生commit
Git format-patch
和 diff
命令都可以生成补丁文件,但它们的格式略有不同,并且通常用于不同的场景,两者生成的补丁文件在文件内容差异部分的格式是非常相似的。 git format-patch
生成的补丁文件实际上也是基于 diff
格式生成的。
3.使用工作树working tree
Git 的工作树(working tree)概念是指当前检出的分支版本所在的文件系统状态。你可以在工作树中查看和修改文件,然后使用 Git 的命令如 add
、commit
、checkout
等进行版本控制。然而,在一些复杂的开发场景中,只使用一个工作树可能不够高效。Git 的多工作树功能(通过 git worktree
命令)允许你在同一仓库的不同分支或相同分支的多个版本上同时工作,从而提升工作效率。一句话说明:工作树允许将不同分支复制一个完整示例到其它目录,允许多个目录并行开发,重要的是并行开发
git checkout -b feature-1 //创建分支
# 在目录 my-project-feature-1 中检出 feature-1 分支
git worktree add ../my-project-feature-1 feature-1
##目录结构会发生改变
parent-directory/
├── my-project
├── my-project-feature-1
#如上my-project-feature-1 和主分支将一模一样
平常使用不到这个功能,可以通过切换分支达到切换代码目的,工作树几个特性:
①切换到对应目录会自动切换分支
②创建新目录其实就是拷贝了主分支下所有文件
③可以使用 git cherry-pick合并别的分支修改
六,常用命令
1.commit 将将暂存内容提交
-m //直接在命令行中提供提交信息,不加的话会进入vim --amend //修改上次提交信息 如果不加-m会进入vim -a //自动把所有已经修改的文件加入到暂存区(不包括新文件)
2.add 修改保存暂存
. -A --all // 这些选项可以将工作区的所有更改(包括修改、删除、新文件)添加到暂存区 -u //工作区中所有已经被跟踪的文件的更改(包括修改和删除,但不包括新文件)添加到暂存区
3.push 推送分支
-u,--set-upstream //当你推送一个新的本地分支到远程仓库时,可以使用这个选项来设置默认的上游仓库和分支,这样在未来只需要简单地运行 git push 或 git pull 就可以推送或拉取更改 -f,--force // 这个选项可以强制推送更改到远程仓库,即使这个操作可能会覆盖远程仓库中现有的提交。可以导致数据丢失 --tags //默认情况下,git push 命令不会推送标签到远程仓库。使用这个选项可以将所有本地新建的标签也推送到远程仓库
4.merge 合并分支
--no-ff(no fast forward) //禁用快进模式fast-forward。即使合并时可以直接将HEAD指针指向目标分支,它也会创建一个新的合并提交。这有助于保留项目的分支结构和合并历史 -m //设置合并消息 注意如果不指定消息,分2个情况:①ff模式:直接移动HEAD ②no-ff:如果没有这个参数git会创建一个commit名字为"Merge brach A into B" --abort //如果合并遇到错误或冲突,使用这个选项可以停止合并,回到合并操作之前的状态。它是一个快速撤销合并尝试的方式 --squash // 将分支的改动合并成一个单独的提交。这在你想要将一个特性分支的所有更改作为一个单独的提交合并到主分支时特别有用,因为它可以使历史更清晰 --continue //当你解决了因为合并造成的冲突后,使用这个命令继续之前尝试的合并。首先需要手动解决冲突并将解决后的文件标记为已解决(通常是通过git add命令),然后使用此命令完成合并过程
5.pull/clone/fetch 获取远程内容
用途与工作阶段 git fetch 主要用于更新本地仓库的信息,不改变工作区和当前分支状态。它适用于想要查看其他人所做更改,但还不准备将这些更改合并到本地工作中的情况。 git pull 则用于更新并合并远程分支的更改到当前分支,适用于希望保持本地分支更新并立即反映远程仓库更改的情况。 git clone 用于完全复制一个远程仓库,适用于初次下载项目代码的情况。 对本地改动的影响 git fetch 不会自动修改你的工作区或者分支,仅仅下载数据。 git pull 会改变你的工作区和当前分支的状态,自动将远程更改合并到本地。 git clone 创建一个全新的本地仓库。
6.log 日志
--oneline //此选项会让每个提交在一行中显示,让历史看起来更干净。默认的 git log 会显示完整的提交 hash、作者、日期和提交消息。
--graph //显示一个 ASCII 图形,代表提交历史的分支和合并情况。
--all //显示所有分支的提交历史,而不仅仅是当前分支
--stat //对每个提交,展示哪些文件被修改,以及每个文件的添加和删除行数
-p,--patch //除了显示常规的提交信息外,还显示每个提交的差异(以 patch 的形式)。这可以让你看到每个提交具体修改了什么
git log --oneline --graph --all
--grep //commit过滤:只显示包含指定字符串的提交。例如,你可以使用它来找到所有含有特定词汇的提交
--author //作者过滤:只显示由特定作者的提交。例如,你可以使用它来找到所有由特定人员进行的提交