前言:git是一个 开源的分布式版本控制系统。
这里的重点理解是 “分布式” ,与之相对立的有 “集中式”(SVN为代表)
1、集中式版本控制系统,版本库是集中存放在中央服务器的, 在生成版本信息和交换数据时都需要网络。集中式版本控制系统最大的缺点就是必须联网才能工作。 简而言之就是只要更改代码就会需要链接中央服务器。
2、分布式版本控制系统 ,生成版本时不依赖网络,交换数据时才需要, 分布式版本控制系统的版本安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,不会影响其他人,届时git重新获取一次。而集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。
常用git工作路径 : 工作区(目录) ==> 暂存区(git add) ==> 本地仓库(git commit) ==> 远程仓库(git push)
公式:git config --global alias.别名 原来Git命令
直接在终端输入命令即可。
git config --global alias.st status // git st
git config --global alias.pl pull. // git pl
git config --global alias.ps push. //git ps
git config --global alias.ci commit // git ci
git config --global alias.lg log //git lg
git config --global alias.co checkout // git co
git config --global alias.br branch //git br
git config --global alias.mg merge //git mg
–pretty: 定义输出格式。您可以使用不同的占位符来自定义显示内容。例如,–pretty=“%h %s” 将只显示提交哈希值和提交消息。
–oneline: 以单行形式输出每个提交的简化信息。每个提交将仅显示 SHA-1 值和提交消息的第一行。
–graph: 以 ASCII 图形形式显示提交历史记录的分支和合并情况。
–author: 按作者过滤提交。例如,–author=“John Doe” 将仅显示由 John Doe 提交的提交。
–since 和 –until: 限制要显示的提交时间范围。例如,–since=“2 weeks ago” 将只显示在过去两周内进行的提交。
–grep: 仅显示包含指定单词或短语的提交。例如,–grep=“bug fix” 将仅显示包含 “bug fix” 这个短语的提交。
-n: 指定要显示的提交数量。例如,-n 5 将仅显示最近的 5 个提交。
这些是 git log 命令中一些常用的参数,但还有许多其他选项和参数可用,您可以根据需要使用它们来过滤、排序和限制输出。请参阅 Git 文档中 git log 部分以获取更多详细信息。
相同点:两者都可以将工作区中所有未跟踪或者修改的文件添加到暂存区。
不同点 :
一、git版本不同引起的区别
1.x版本:
(1)git add all可以提交未跟踪、修改和删除文件。
(2)git add .可以提交未跟踪和修改文件,但是不处理删除文件。
2.x版本:
两者功能在提交类型方面是相同的。
二.所在目录不同导致的差异:
(1)git add all无论在哪个目录执行都会提交相应文件。(根目录)
(2)git add .只能够提交当前目录或者它后代目录下相应文件。
git commit -am可以省略使用git add命令将已跟踪文件放到暂存区
的功能。但是未跟踪的文件不适用。
注意:但是新的文件需要使用git add 来跟踪新文件
(1)想要找某人 某些人 commit
git log --oneline --author="name"
git log --oneline --author="name1/|name2"
(注意需要再 | 前面加上 / 注明是功能符号)
(2)想要找某关键字 commit (模糊查询)
git log --grep="关键字"
(3)想要找某段时间 commit
----2023.3.20这一天的上午9点到12点的commit。
git log --since="2023-03-20 09:00:00" --until="2023-03-20 12:00:00"
有以下四种方式:
1、把.git目录整个删除(不建议);
2、使用git rebase 命令来改动历史记录;
3、先把commit 用git reset 命令删除,整理好后再重新commit; ( 可以查看 目录7 )
4、使用 --amend 参数修改最后一次的commit。
2)
git rebase -i
命令可以打开交互式界面,让我们对即将被复制的提交进行编辑或删除。通过使用 -i 选项,我们可以指定要复制的提交范围,进入交互式界面后,我们可以为每个提交指定操作类型(如 pick、edit、squash、fixup 等),并对提交信息进行编辑。
1、执行命令 git rebase -i HEAD~n
,其中 n 是你想要更改的最近几次提交的数量。这将会打开一个交互式的文本编辑器。
2、在编辑器中,你会看到一个类似于下面的内容:
pick abc123 commit message 1
pick def456 commit message 2
pick ghi789 commit message 3
每一行代表一次提交,并且以 pick 命令开始。在这里,你可以对每个提交进行操作,包括重新排序、编辑提交信息、合并提交等。
3、根据需要修改每个提交的命令。例如,如果你想要合并第二个和第三个提交,可以将第二个提交的命令修改为 squash 或 fixup,表示将其合并到第一个提交中。你也可以修改提交信息,例如,将第一个提交的信息从 “commit message 1” 修改为 “new commit message 1”。
4、保存并关闭编辑器,Git 将会根据你的操作重写提交历史记录。请注意,这可能会更改提交的哈希值,因此如果你将已经推送到远程仓库的提交作为目标,你需要小心处理。
总之,使用 git rebase -i 命令可以方便地更改提交历史记录,但需要小心操作,以免不必要的麻烦。
4)
要改动最后一次的commit信息,可以使用 --amend参数进行commit。
该指令可以修改最后一次提交的提交信息。它允许更改提交消息,并添加或删除文件。它同时还可以用来纠正上一次提交的错误。在修改提交信息之前,确保没有其他人已经在该分支上进行了工作,并且确保不会破坏其他人的工作。
git commit --amend -m "修改的新信息"
假如使用git rm test.html
误删除了test.html文件,
需要找回可以使用命令
git checkout test.html
进行找回文件。
注意:git checkout 命令时 git会切换到指定的分支,但是如果后跟的是文件名或者是路径,git就不会切换分支,而是把该文件从.git目录中复制一份到当前工作目录。
如果使用。git checkout .
就等同于将当前目录的所有文件都回复到上一次commit的状态。
如果想要拆掉最后一次的commit 可以采用“相对”,“绝对”的做法 。
相对做法:
git reset --soft HEAD^
(注意,仅仅是撤回commit操作,您写的代码仍然保留。)
最后的那个^ 代表的是上一次,所以这个指令的意思是:上一个版本的commit,如果是前两次就 HEAD^^
. 如果是前5次HEAD~5
绝对做法:
如果你很清楚想要把当前的状态回退到哪一个commit ,可以直接指明
git reset e65d7ed
表示直接回退到 e65d7ed版本。
- -mixed
是默认的参数,不删除工作空间改动代码,撤销commit,并且撤销git add。也就是说,commit拆出来的文件会留在工作目录,但是不会留在暂存区。
操作这个为默认参数,git reset --mixed HEAD^ 和 git reset HEAD^ 效果是一样的。
- -soft
不删除工作空间改动代码,撤销commit,不撤销git add 。就是说commit拆出来的文件会直接放在暂存区。
- -hard
删除工作空间改动代码,撤销commit,撤销git add 。无论是工作目录还是暂存区的文件都会被删除。
注意完成这个操作后,就完全恢复到了上一次的commit状态。
git merge和git rebase都是用来将两个分支合并的Git命令,但它们之间有一些重要的区别。
1、git merge命令会将两个分支的历史记录合并成一个新的提交。在这种情况下,Git会创建一个新的提交来合并两个分支,并且保留每个分支的历史记录。该操作会创建一个新的合并提交,并将其添加到当前分支上。
2、git rebase命令也是用于合并两个分支,但它与git merge的工作方式不同。当我们运行git rebase命令时,Git会将我们正在进行的分支(通常是特性分支)的提交应用于目标分支的末端,而不是创建新的合并提交。在这种情况下,Git会将当前分支的所有提交记录重新播放到目标分支的顶部,然后将HEAD指针指向该分支。
3、这意味着,如果我们使用git rebase来合并分支,我们的提交历史记录将会更为线性化。这使得更容易查看和理解我们代码库的变更历史。另外,使用git rebase可能会减少合并冲突的数量,因为我们可以在合并之前将我们的更改整理成更合适的形式。
总的来说,git merge和git rebase都可以用来合并分支,但它们的工作方式不同。如果我们想要保留分支的历史记录并创建一个新的合并提交,那么使用git merge是更好的选择。如果我们想要使分支历史记录更线性化,并且减少可能出现的冲突数量,那么使用git rebase是更好的选择。
下面是一个使用git merge和git rebase的示例,帮助更好地理解它们之间的区别。
首先,我们有两个分支 - 主分支(master)和特性分支(feature):
A --- B --- C master
\
D --- E feature
在这里,提交C是最后一个添加到主分支上的提交,而提交E是最后一个添加到特性分支上的提交。
1、假设现在想要将特性分支合并到主分支上。可以使用git merge命令来执行此操作:
$ git checkout master
$ git merge feature
这会创建一个新的合并提交,并将其添加到主分支上:
A --- B --- C ------ F master
\ /
D ---- E feature
注意,这里的提交F是一个新的合并提交,它将主分支和特性分支中的更改结合在一起。
2、现在,使用git rebase命令进行相同操作的效果:
$ git checkout feature
$ git rebase master
在这种情况下,Git会从特性分支的顶部(即提交E)开始重新播放所有提交,然后将结果应用于主分支的末尾。这会产生以下结果:
A --- B --- C --- D' --- E' feature
\
D --- E
注意,在这种情况下,历史记录变得更为线性化,**因为我们将特性分支的提交重新应用于主分支的顶部,而没有创建新的合并提交。**这使得最终历史记录更容易查看和理解。
总的来说,git merge会创建一个新的合并提交,而git rebase则会线性化历史记录并将其应用于目标分支末尾。根据需求和项目情况,选择不同的操作是很重要的。
假如现在有master M以a b两个分支(都是基于master)并且都更新了A’ B’;
-------A-------A' (a)
/
M (master)
\
B-------B' (b)
这是如果b合并merge a,那么会重新新建一个commit对象c指向A’ B’
-------A-------A' (a)
/ \
M (master) C (b)
\ /
B-------B'
但是如果是 master合并a ,a分支是从master分支出去的,领先master分支 commit成为A’。如果这个时候回到master合并a,git就会自动选用 快转模式fast-forward ,就是不会新增一个新的commit对象,就是等于将master的指针指向了A’。这有一个弊端就是,合并后分别不出来当前代码是再M还是在A’分支上更新的内容。
加上这个后缀后,即便是 master与基于它分支的A’进行合并merge 会新建一个commit对象,里面就可以分辨出代码是来自于哪个分支更新的。
如果有冲突,可以按照以下步骤解决:
1、在发生冲突的分支上,使用 git status
命令查看文件列表和冲突信息。
2、手动编辑文件并解决冲突。在编辑完所有冲突之后,将文件保存并使用git add
命令将其标记为已解决。
3、使用git rebase --continue
命令继续进行rebase操作。如果不想解决此冲突,则可以使用git rebase --skip
命令跳过当前补丁并应用下一个补丁。
4、如果想中止rebase操作并回到先前的状态,请使用git rebase --abort
命令。
git cherry-pick它可以将另一个分支(或同一分支中的不同提交)中的一个或多个提交应用到当前分支上。
使用 git cherry-pick 命令时,请提供要应用的提交的SHA或引用。例如:
git cherry-pick
这会将指定提交应用到当前分支上。如果您想将多个提交合并到当前分支上,则可以在一个命令中指定多个提交:
git cherry-pick
请注意,在使用git cherry-pick
命令时,可能会发生冲突。在这种情况下,您需要手动解决冲突,然后使用git add
命令标记文件为已解决,并使用git cherry-pick --continue
命令继续cherry-pick操作。如果您想放弃此次cherry-pick操作,可以使用 git cherry-pick --abort
命令撤销该操作。
假设现在有两个分支,即 main 分支和 feature 分支。在 feature 分支中,有一个提交(例如 commit-A)包含一些更改,想将其应用到 main 分支上。这时可以使用 git cherry-pick 命令。
1、首先,保险起见,从 main 分支上新建出一个新分支:
git checkout -b new-feature main
现在已经在 new-feature 分支上了。然后使用 git log 命令查看 feature 分支上提交的历史记录,并找到要应用到 main 分支上的提交的 SHA 值(例如 commit-A)。
2、接下来使用 git cherry-pick 命令将提交复制到当前分支(即 new-feature 分支)上:
git cherry-pick commit-A
3、这会将 commit-A 中的更改应用到 new-feature 分支上。如果该提交导致冲突,则需要手动解决冲突并标记文件为已解决:
git add
4、然后使用 git cherry-pick --continue 命令继续cherry-pick操作:
git cherry-pick --continue
如果想跳过此提交并继续cherry-pick操作,请使用 git cherry-pick --skip 命令:
git cherry-pick --skip
如果想放弃此次cherry-pick操作并回到开始时的状态,请使用 git cherry-pick --abort 命令:
git cherry-pick --abort
最后,当 new-feature 分支上的更改完成并测试通过后,可以将其合并到 main 分支上:
git checkout main
git merge new-feature
这里我们需要清晰一个概念:分支只是一个指向某个commit对象的指向标,他就像一张贴纸一样贴在了commit对象是上。
所以删除了分支,只是等于是将贴在commit对象上的贴纸撕掉了,但是commit对象是依旧存在的。想要恢复,只需要找到删掉的分支它所指向的commit对象的SHA-1值。
比如有一个分支为 A 它指向的commit的SHA-1是 b172a5s
, 这个时候不小心将A删了。想要找回。
git branch new_A b172a5s
执行这个命令后,new_A这个分支就是找回以前的A。
其实合并分支,并不是所谓真的合并的就是分支,可以说是 合并commit,合并的是分支所指向的那个commit。
1、我常使用的就是git rebase --abort
,会失去rebase 过程中所做的所有更改。
2、git reset --hard
在撤销上一次commit操作可以使用git reset --hard HEAD^
但是使用rebase后不能这么撤销,因为rabse是把自己的commit的对象依次应用到目标分支上 如图:
---------A-----A'(a)
/
M
\
B-----B'(b)
这个时候如果 在 a分支上rebase b会发生的事:
---------A-----A'
/
M
\
B-----B'(b)----A1----A'1(a)
rebase 并没有做出那个专门为了合并的commit ,而是整个串在一起了,所以这个时候使用git reset --hard HEAD^
, 只会删除最后一个commit,但是并不会回到rebase前。
使用git reflog 找到开始rebase前的最后动作,那个commit的SHA-1
然后 git reset --hard
就可以回到rebase前了。
在 Git 中,我们可以使用 git stash 命令在一个代码分支中保存多个 stash,这对于同时处理多个功能或者处理紧急问题等情况非常有用。
默认情况下,Git 会为每个新的 stash 创建一个唯一的名称,例如 stash@{0}、stash@{1} 等。而当我们需要恢复某个 stash 时,可以使用 git stash apply 或者 git stash pop 命令来应用指定的 stash。
以下是几个常见的多个 stash 操作:
1、保存多个 stash
当我们需要保存多个 stash 时,可以重复使用 git stash save 命令来创建新的 stash。例如,在分别完成了 Feature A 和 Feature B 的开发之后,可以分别将它们保存到两个不同的 stash 中:
$ git stash save "Feature A"
Saved working directory and index state On master: Feature A
$ git stash save "Feature B"
Saved working directory and index state On master: Feature B
2、 查看多个 stash
当我们需要查看多个 stash 时,可以使用 git stash list 命令来列出所有的 stash。例如,列出当前分支中所有的 stash 及其对应的说明信息:
$ git stash list
stash@{0}: On master: Feature B
stash@{1}: On master: Feature A
3、 应用指定的 stash
当我们需要应用指定的 stash 时,可以使用 git stash apply 或者 git stash pop 命令来恢复指定的 stash。例如,应用上面示例中的 Feature A:
$ git stash apply stash@{1}
4、删除指定的 stash
当我们需要删除指定的 stash 时,可以使用 git stash drop 命令来删除指定的 stash。例如,删除上面示例中的第二个 Feature B:
$ git stash drop stash@{0}
5、清空所有的 stash
当我们需要清空所有的 stash 时,可以使用 git stash clear 命令来清空所有的 stash:
$ git stash clear
以上就是在 Git 中处理多个 stash 的常见操作。