还可以这样玩?Git基本原理及各种骚操作 ,涨知识了

git diff commit-id commit-id

git show

查看指定标签的提交信息

git show tag-name

查看具体的某次改动

git show commit-id

git log

指定文件夹 log

git log --pretty=format:“%h %cn %s %cd” --author=“iisheng|胜哥” --date=short src

查看指定用户指定format 提交

git log --pretty=format:“%h %cn %s %cd” --author=iisheng --date=short

查看该文件的改动历史

git log --pretty=oneline file

图形化查看历史提交

git log --graph --pretty=oneline --abbrev-commit

统计仓库提交排名前5

git log --pretty=‘%aN’ | sort | uniq -c | sort -k1 -n -r | head -n 5

查看指定用户添加代码行数,和删除代码行数

git log --author=“iisheng” --pretty=tformat: --numstat | awk ‘{ add += $1 ; subs += $2 } END { printf “added lines: %s removed lines : %s \n”,add,subs }’

git rebase

将指定分支合并到当前分支

git rebase branch-name

执行commit id 将rebase 停留在指定commit 处

git rebase -i commit-id

执行commit id 将rebase 停留在 项目首次commit处

git rebase -i --root

git restore

恢复第一次add 的文件,同 git rm --cached

git restore --staged file

移除staging区的文件,同 git checkout

git restore file

git revert

撤销前一次commit

git revert HEAD

撤销前前一次commit

git revert HEAD^

撤销指定某次commit

git revert commit-id

Git骚操作


Git命令不能自动补全?(Mac版)

我见过有的人使用Git别名,反正因为有自动补全的存在,我从来没用过Git别名。不过我的确将我的rm -rf命令替换成了别的脚本了…

安装bash-completion

brew install bash-completion

添加 bash-completion 到~/.bash_profile:

if [ -f $(brew --prefix)/etc/bash_completion ]; then

. $(brew --prefix)/etc/bash_completion

fi

shell有不同种类,我这里使用的是bash

代码没写完,突然要切换到别的分支怎么办?

暂存未提交的代码

git stash

还原暂存的代码

git stash apply

怎么合并其他分支的指定Commit?

使用cherry-pick命令

git cherry-pick 指定commit-id

本地临时代码不想提交,怎么一次性清空?

还原未commit的本地更改的代码

git reset --hard

还原包含commit的代码,到跟远程分支相同

git reset --hard origin/master

已经提交的代码,不需要了,怎么当做没提交过?

还原到上次commit

git reset --hard HEAD^

还原到当前之前的几次commit

git reset --hard HEAD~2

强制推送到远程分支,确保没有其他人在push,不然可能会丢失代码

git push origin develop --force

历史commit作者邮箱写错了,怎么一次性改过来?

使用git filter-branch命令。

复制下面的脚本,替换相关变量

  • OLD_EMAIL

  • CORRECT_NAME

  • CORRECT_EMAIL

脚本如下:

#!/bin/sh

git filter-branch --env-filter ’

OLD_EMAIL=“your-old-email@example.com”

CORRECT_NAME=“Your Correct Name”

CORRECT_EMAIL=“your-correct-email@example.com”

if [ “ G I T C O M M I T T E R E M A I L " = " GIT_COMMITTER_EMAIL" = " GITCOMMITTEREMAIL"="OLD_EMAIL” ]

then

export GIT_COMMITTER_NAME=“$CORRECT_NAME”

export GIT_COMMITTER_EMAIL=“$CORRECT_EMAIL”

fi

if [ “ G I T A U T H O R E M A I L " = " GIT_AUTHOR_EMAIL" = " GITAUTHOREMAIL"="OLD_EMAIL” ]

then

export GIT_AUTHOR_NAME=“$CORRECT_NAME”

export GIT_AUTHOR_EMAIL=“$CORRECT_EMAIL”

fi

’ --tag-name-filter cat – --branches --tags

强制推送替换

git push --force --tags origin ‘refs/heads/*’

不小心把不该提交的文件commit了,怎么永久删除?

也是使用git filter-branch命令。

git filter-branch --force --index-filter \

“git rm --cached --ignore-unmatch FILE-PATH-AND-NAME” \

–prune-empty --tag-name-filter cat – --all

强制推送覆盖远程分支。

git push origin --force --all

强制推送覆盖远程tag

git push origin --force --tags

怎么保证团队成员提交的代码都是可运行的?

这里想说的是使用git hooks,一般在项目目录.git/hooks,客户端可以使用hooks,控制团队commit提交规范,或者push之前,自动编译项目校验项目可运行。服务端可以使用hooks,控制push之后自动构建项目,merge等自动触发单元测试等。

git reset --hard命令,执行错了,能恢复吗?

查看当前commit log

误操作git reset --hard 8529cb7

执行git reflog

还原到之前的样子

公司使用GitLab,平时还用GitHub,多账号SSH,如何配置?

编辑 ~/.ssh/config文件 没有就创建

github

Host github.com

Port 22

HostName github.com

PreferredAuthentications publickey

AddKeysToAgent yes

IdentityFile ~/.ssh/github_id_rsa

UseKeychain yes

User iisheng

gitlab

Host gitlab.iisheng.cn

Port 22

HostName gitlab.iisheng.cn

PreferredAuthentications publickey

AddKeysToAgent yes

IdentityFile ~/.ssh/gitlab_id_rsa

UseKeychain yes

User iisheng

Git commits历史如何变得清爽起来?

多用git rebase

比如,开发分支是feature,主干分支是master。我们在进行代码合并的时候,可以执行下面的命令。

切换当前分支到feature

git checkout feature

将当前分支代码变基为基于master

git rebase master

然后我们再切换到master分支,执行git merge feature,就可以进行快进式合并了,commmits历史就不会有交叉了。后文我们会详细讲解。

git rebase会更改commit历史,请谨慎使用。

下面的图是Guava项目的commit记录。

如何修改已经提交的commit信息?

原始Git提交记录是这样的

执行git rebase -i 070943d,对指定commitId之前的提交,进行修改

修改后Git提交记录变成了这样

git rebase -i非常实用,还可以将多个commit合并成一个等很多事情,务必要记下。

不小心执行了git stash clear怎么办?

git fsck --lost-found

执行之后,可以找到相关丢失的commit-id,然后merge一下即可。

该命令上可以找回git add之后被弄丢的文件。

啥?你没执行过git add代码就丢了?别怕,一般编译器有Local History赶紧去试试吧。

详解git merge


我们执行git merge命令的时候,经常会看到Fast-forward字样,Fast-forward到底是个什么东西?

其实,git merge一般有三种场景。

快进式合并

举个栗子,假如初始存在masterhotfix分支是这样的。

然后我们在hotfix分支加了些代码,分支变成这样了。

这个时候,我们将hotfix分支,mergemaster,即执行git merge hotfix

由于的分支hotfix所指向的提交C3C2的直接后继, 因此Git会直接将指针向前移动。换句话说,如果顺着一个分支走下去能够到达另一个分支,那么Git在合并两者的时候, 只会简单的将指针向前推进(指针右移),因为这种情况下的合并操作没有需要解决的分歧——这就叫做 快进(fast-forward)

三方合并

再举个栗子,假如初始存在featuremaster分支情况是这样的。

然后我们在feature分支加了些代码,而master分支也有人加了代码,现在分支变成这样了。

这个时候,我们将feature分支,mergemaster,即执行git merge feature

和之前将分支指针向前推进所不同的是,Git将此次三方合并的结果做了一个新的快照并且自动创建一个新的提交指向它。这个被称作一次合并提交,它的特别之处在于他有不止一个父提交。

所以我们也知道了,为什么有的时候merge之后会产生新的commit,而有的时候没有。

遇到冲突时的合并

如果在两个分支分别对同一个文件做了改动,Git就没法直接合并他们。当遇到冲突的时候,Git会自动停下来,等待我们解决冲突。就像这样

$ git merge dev

Auto-merging 111.txt

CONFLICT (content): Merge conflict in 111.txt

Automatic merge failed; fix conflicts and then commit the result.

我们可以在合并冲突后的任意时刻使用git status命令来查看那些因包含合并冲突而处于未合并unmerged状态的文件。

$ git status

On branch master

You have unmerged paths.

(fix conflicts and run “git commit”)

(use “git merge --abort” to abort the merge)

Unmerged paths:

(use “git add …” to mark resolution)

both modified: 111.txt

no changes added to commit (use “git add” and/or “git commit -a”)

待解决冲突的文件Git会以未合并的状态标识出来,出现冲突的文件会出现一些特殊的区段,看起来像下面的样子。

<<<<<<< HEAD

111aaa

=======

111b

dev

<<<<<<<后面的是当前分支的引用,我们的例子中,就代表master分支。>>>>>>>后面表示的是要合并到当前分支的分支,即dev分支。=======的上半部分,表示当前分支的代码。下半部分表示dev分支的代码。

我们可以把上面的测试内容改成下面的样子来解决冲突

111aaa

在解决了所有文件里的冲突之后,对每个文件使用git add命令来将其标记为冲突已解决。

解决冲突的过程中,每一步都可以执行git status查看当前状态,Git也会给出相应提示,进行下一步操作。当我们所有的文件都暂存之后时,执行git status时,Git会给我们看起来像下面的这种提示

$ git status

On branch master

All conflicts fixed but you are still merging.

(use “git commit” to conclude merge)

然后,我们根据提示执行git commit

Merge branch ‘dev’

Conflicts:

111.txt

It looks like you may be committing a merge.

If this is not correct, please remove the file

.git/MERGE_HEAD

and try again.

Please enter the commit message for your changes. Lines starting

with ‘#’ will be ignored, and an empty message aborts the commit.

On branch master

All conflicts fixed but you are still merging.

然后,我们保存这次提交就完成了这次冲突合并。

详解git rebase


rebase做了什么

举个栗子。我们同样用刚才merge的场景。

如果不用rebase,使用merge是下面这样的,合并分支的时候会产生一个合并提交,而且会有分支交叉的情况。

使用rebase是下面这样的。

然后,切换到master分支,进行一次快进式合并。

变基实际上就是基于其他分支重塑当前分支。变基之后,当前分支就相当于是基于最新的其他分支新加了一些commit,这样的话就可以进行快进式合并了。

rebase原理

它的原理是首先找到这两个分支(即当前分支 dev、变基操作的目标基底分支master)的最近共同祖先 C2,然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件, 然后将当前分支指向目标基底C3, 最后以此将之前另存为临时文件的修改依序应用,也就是在C3后面添加C4'C5'

Git对象与快照


提到Git,总有人会说快照快照是个什么鬼?

实际上,Git是一个内容寻址文件系统,其核心部分是一个简单的键值对数据库。将Git中的对象,存储在.git/objects目录下。

Git对象主要分为,数据对象(blob object)树对象(tree object)提交对象(commit object)标签对象(tag object)

数据对象

我们新建一个目录,然后在该目录下执行git init初始化一个Git项目。

然后,查看.git/objects目录下都有什么。

$ find .git/objects

.git/objects

.git/objects/pack

.git/objects/info

接着,我们写一个文件echo '1111' > 111.txt,并执行git add之后,再查看。

$ find .git/objects

.git/objects

.git/objects/5f

.git/objects/5f/2f16bfff90e6620509c0cf442e7a3586dad8fb

.git/objects/pack

.git/objects/info

我们发现.git/objects目录下,多了个文件和目录。实际上,Git会将我们的文件数据外加一个头部信息header一起做SHA-1校验运算而得到校验和。然后,校验和的前2个字符用于命名子目录,余下的38个字符则用作文件名。

我们可以使用下面的命令,显示在Git对象中存储的内容。

$ git cat-file -p 5f2f16bfff90e6620509c0cf442e7a3586dad8fb

1111

这就是我们在上文写入的文件内容。

上述类型的对象称之为数据对象(blob object)。数据对象,仅保存了文件内容,而文件名字没有被保存。

树对象

数据对象大致对应UNIX中的inodes或文件内容,树对象则对应了UNIX中的目录项。一个树对象包含了一条或多条树对象记录(tree entry),每条记录含有一个指向数据对象或者子树对象的SHA-1指针,以及相应的模式、类型、文件名信息。

通常,Git根据某一时刻暂存区(即index区域)所表示的状态创建并记录一个对应的树对象。

当我们执行过git add之后,暂存区就有内容了,我们可以通过Git底层命令,生成树对象。

$ git write-tree

b716c7b049ccd9048b0566a57cfd516c17c1e39f

查看该树对象的内容。

$ git cat-file -p b716c7b049ccd9048b0566a57cfd516c17c1e39f

100644 blob 5f2f16bfff90e6620509c0cf442e7a3586dad8fb 111.txt

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

1200页Java架构面试专题及答案

小编整理不易,对这份1200页Java架构面试专题及答案感兴趣劳烦帮忙转发/点赞

百度、字节、美团等大厂常见面试题

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!
file -p b716c7b049ccd9048b0566a57cfd516c17c1e39f

100644 blob 5f2f16bfff90e6620509c0cf442e7a3586dad8fb 111.txt

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-moHnsUsQ-1712517330307)]

[外链图片转存中…(img-Yqa8O4eO-1712517330308)]

[外链图片转存中…(img-G2lEMUzB-1712517330308)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

1200页Java架构面试专题及答案

小编整理不易,对这份1200页Java架构面试专题及答案感兴趣劳烦帮忙转发/点赞

[外链图片转存中…(img-gWUcmlJw-1712517330308)]

[外链图片转存中…(img-7AoYGud7-1712517330308)]

百度、字节、美团等大厂常见面试题

[外链图片转存中…(img-psE5H2uS-1712517330309)]

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值