如何全面处理 Git?
内容提要
本文介绍Git常见操作:用git add/commit/push提交更新;git commit --amend修改上次提交;git rm --cached删除远程文件;git pull等于fetch加merge,冲突需手动编辑后提交;git merge -s ours覆盖分支;git branch -d删除分支;git reflog回滚指定提交;git commit -a仅自动添加已跟踪文件;.gitignore用*和!排除例外;git reset --hard放弃修改;git clone -b克隆指定分支。
延伸解读
amend 与 force push 的风险
文章提到用 git commit --amend 修改上次提交后,需要 git push --force 推送到远程。但作者特别警告 --force 是危险的,并指出 Linus 不推荐这种做法。这是因为强制推送会覆盖远程历史,如果其他人已经基于旧提交进行了工作,可能会导致他们的提交丢失或产生混乱。因此,在使用 --force 前,务必确认没有其他人依赖该分支,或考虑使用更安全的 --force-with-lease。
pull 与 fetch 的本质区别
文章引用 StackOverflow 的解释:git pull 等于 git fetch 加 git merge。git fetch 只更新远程跟踪分支,不会改变本地分支或工作区,因此是安全的,甚至可以定期在后台运行。而 git pull 会将远程分支的更新合并到本地当前分支,可能引发冲突。如果自动合并失败,需要手动编辑冲突文件(注意 <<<<<<< 和 >>>>>>> 标记),然后提交。理解这一区别有助于选择更可控的工作流程。
commit -a 的适用场景与局限
很多人想用 git commit -a 来合并 add 和 commit 步骤,但文章指出它只对已经跟踪过的文件自动执行 add,对于未跟踪的新文件无效,仍需手动 git add。如果你经常需要添加新文件,可以考虑设置别名来简化操作。因此,commit -a 适合快速提交已跟踪文件的修改,但不适合包含新文件的提交。
reset --hard 与 reflog 回滚
文章提到用 git reset --hard HEAD^ 可以放弃自上次提交以来的所有修改,回到上一个提交状态。但这是一个危险操作,会永久丢弃工作区和暂存区的更改。如果需要回滚到更早的特定提交,可以使用 git reflog show 找到提交哈希,然后 git checkout 该哈希。reflog 记录了所有 HEAD 的移动,是恢复误操作的重要工具,但注意 checkout 特定提交会进入分离头指针状态。
Q&A
如何修改文件并更新到远程仓库?
使用 git add file 添加文件,然后 git commit -m "提交信息" 提交,最后 git push origin branch_name 推送到远程仓库。也可以使用 git commit -am "提交信息" 来同时添加已跟踪文件并提交。
git pull 和 git fetch 有什么区别?
git pull 相当于 git fetch 后跟 git merge,会更新本地分支并合并远程更改;而 git fetch 只更新远程跟踪分支,不会改变本地分支和工作区,更安全。
如何删除远程仓库中的文件?
可以使用 git rm --cached file_to_delete 删除远程仓库中的文件,也可以使用通配符删除多个文件,如 git rm --cached 'merge-*' 删除所有以 merge- 开头的文件。
如何回滚到特定的提交?
使用 git reflog show 找到目标提交的哈希值,然后执行 git checkout revision_hash 即可回滚到该提交。
git commit -a 和 git add 后 commit 有什么区别?
git commit -a 只会自动添加已跟踪的文件,对于未跟踪的文件仍需手动 git add。而先 git add 再 commit 可以添加任何文件,包括未跟踪的。
如何忽略所有文件但保留某个特定文件?
在 .gitignore 文件中添加:* 和 !except_script.sh,这样会忽略所有文件,但 except_script.sh 除外。