>参考:[ProGit 2 中文版](https://git-scm.com/book/zh/v2) ## 基本操作 ### 批量删除本地分支 参考:https://blog.csdn.net/qq_32452623/article/details/86317091 ```shell git branch | grep 'xxx' | xargs git branch -D ``` > xargs 可以将 stdin 中以空格或换行符进行分隔的数据,形成以空格分隔的参数,传递给其他命令 ### 初始化仓库 1. 克隆 git clone [url] 2. 初始化本地项目作为git仓库,在项目根目录执行 git init,然后将项目文件添加到仓库 git add * 3. 将已有本地项目推送到远程仓库 1. 如果本地项目还未初始化为git仓库,参考第2种方法初始化为git仓库 2. 添加远程仓库 git remote add [name] [url] 3. 推送 git push ### 撤消操作 1. 重新提交 有时候我们提交完了才**发现漏掉了几个文件没有添加**,或者**提交信息写错了**。此时,可以运行带有 --amend 选项的提交命令尝试重新提交,比如 ```bash git commit -m 'initial commit' git add forgotten_file git commit --amend [message] ``` > 在 TortiseGit 和 IDEA 的Commit界面都有明显的 Amend 的选项。 2. 撤销修改 ```bash git checkout -- filename ``` 3. 撤消已提交未推送的Commit 我们提交完了**才发现不应该提交到这个分支上**。此时执行下面命令,将提交撤回。 ```bash git reset --hard ``` 2. 撤消已推送的Commit ### 修改跟踪分支 ```shell git branch -u origin/serverfix ``` ## Git Reset 参考:https://www.jianshu.com/p/c2ec5f06cf1a **工作目录** -> **暂存区** -> **仓库** `git add ` 会将文件添加到暂存区,`git commit` 会将暂存区的文件提交到仓库 `git reset [option] ` 会将HEAD和分支的指针移动到 CommitID 上 参数: * --mixed 保留工作目录,重置暂存区 * --soft 保留工作目录和暂存区的文件 * --hard 重置工作目录和暂存区 ![Git Reset演示图.drawio.png](./imgs/GitReset演示图.drawio.png) ## Git Rebase 参考:[git rebase 合并多次提交](https://www.cnblogs.com/jmcui/p/9723272.html) ```shell git rebase -i commitId ## 将要合并的提交的pick改为s git rebase --continue ``` > 在IDEA中使用 git reabase :在下方 Version Control 栏中,右键某次 Commit,点击 【Interactively Rebase from Here...】 ## Git cherry-pick 参考 [git将某分支的某次提交合并到另一分支](https://www.cnblogs.com/myitnews/p/12363154.html) 1. 复制某分支的提交ID 2. 切换到当前分支,执行 `git cherry-pick commitId` > 该操作可能会引起冲突,慎重! ```mer graph TD a-->b ``` ## Git 常见问题 1. git clone 密码输入错误后不再弹出输入框 解决方法: 控制面板 -> 用户账户 -> 凭据管理器 -> Windows 凭据 -> 普通凭证 -> 点击修改密码 2. Git 遇到了 The remote end hung up unexpectedly – early EOF – index-pack failed 问题 > 参考: > https://stackoverflow.com/questions/21277806/fatal-early-eof-fatal-index-pack-failed > 今天想 clone 在 gitlab 的 repo,结果在 clone 的过程中遇到了下面的错误。 ```bash $ git clone -v git://192.168.8.5/butterfly025.git Cloning into ‘butterfly025’… remote: Counting objects: 4846, done. remote: Compressing objects: 100% (3256/3256), done. fatal: read error: Invalid argument, 255.05 MiB | 1.35 MiB/s fatal: early EOF fatal: index-pack failed ``` First, turn off compression: ```shell git config --global core.compression 0 ``` Next, let’s do a partial clone to truncate the amount of info coming down: ```shell git clone --depth 1 ``` When that works, go into the new directory and retrieve the rest of the clone: ```shell git fetch --unshallow ``` or, alternately, ```shell git fetch --depth=2147483647 ``` Now, do a regular pull: ```shell git pull --all ``` I think there is a glitch with msysgit in the 1.8.x versions that exacerbates these symptoms, so another option is to try with an earlier version of git (<= 1.8.3, I think). ## Git 工作流 ![](imgs/Pasted%20image%2020221014174452.png) 该种工作流会相对复杂一点,但非常适合用来管理大型项目的发布和维护。贯穿整个开发周期,master和develop分支是一直存在的。 master分支可以被视为稳定的分支,一般不允许直接往master分支提交代码,只允许往这个分支发起merge request,只允许release分支和hotfix分支进行合流。 develop分支是相对稳定的分支,用于日常开发,包括代码优化、功能性开发。 feature分支从develop分支拉取,特性开发会在其上进行,开发完毕合后并到develop分支。 release分支从develop分支拉取,用于回归测试,完成后打tag并合入master和develop。 hotfix分支用于紧急修复上线版本的问题,修复后打tag并合入master和develop。 ## Git 钩子 Git钩子是一组脚本,这些脚本对应着Git仓库中的特定事件,每一次事件发生时,钩子会被触发。这允许你可以定制化Git的内部行为,在开发周期中的关键点上触发执行定制化的脚本。 钩子脚本文件通常放置于项目目录的`.git/hooks`文件夹下。Git会在初始化项目时自动在这个文件夹下放置一些样例脚本。如果你查看`.git/hooks`文件夹下,会找到如下的文件: ```bash applypatch-msg.sample pre-push.sample commit-msg.sample pre-rebase.sample post-update.sample prepare-commit-msg.sample pre-applypatch.sample update.sample pre-commit.sample ``` 这些文件基本上涵盖了可以使用的钩子,只不过`.sample`扩展名不会让脚本内容生效。 **安装一个钩子最简单的方式就是删除`.sample`扩展名。或者如果你从头开始写好了一个钩子脚本,只需要将其命名为上面所列的文件名并去除`.sample`扩展名。** ### 提交消息后追加分支名称 ```shell #!/bin/sh COMMIT_MSG_FILE=$1 COMMIT_SOURCE=$2 SHA1=$3 #提交信息 COMMIT_MSG=`cat $COMMIT_MSG_FILE` #当前分支名称 BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD) #判断提交信息中是否包含当前分支名称 RESULT=$(echo $COMMIT_MSG | grep "${BRANCH_NAME}") #如果不包含,则追加分支名称 if [[ "$RESULT" == "" ]] then #换行 echo " " >> "$COMMIT_MSG_FILE" #追加信息 echo "#$BRANCH_NAME" >> "$COMMIT_MSG_FILE" fi if test -z "$COMMIT_SOURCE" then /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" fi ``` ![](imgs/Pasted%20image%2020221027112350.png)