初探Git:理解和使用版本控制的魔法

发布时间 2024-01-07 23:44:46作者: StarLikeRain

 

 

 遥远的古代,有一位美丽的仙女叫做嫦娥。她的丈夫后羿获得了令人长生不老的鹿骨露。一天,嫦娥在好奇心的驱使下,独自偷喝了这瓶仙药。 喝下仙药的瞬间,嫦娥发现自己开始飘起,越飘越高,最后飘向了月亮。嫦娥惊慌失措,她突然意识到,自己做了一个错误的决定,她非常后悔,但一切已经无法改变,她只能在月亮上度过寂寞的生活。 如果嫦娥的世界有Git这样的版本控制工具,事情可能会完全不同。她偷喝仙药的决定就像我们在编程时对代码的修改,而她后悔的感觉,就像我们在发布代码后发现了重大的错误。 如果之前喝仙药的决定被记录在Git中,像进行一次commit操作,嫦娥就可以使用`git revert`撤销这个决定,就像撤销一次错误的代码提交。或者她可以使用`git reset --hard`命令,回到偷喝仙药之前的状态,就像我们将代码回滚到之前的某个版本。 重写的故事也许有些荒诞,但它生动地描绘了Git工具的强大之处。在代码的世界里,我们有能力前进也可以后退;我们可以修正错误,也可以尝试新的可能。这种灵活性让我们可以更有信心地进行工作,因为我们知道,即使我们做了错误的决定,也总有机会改正它。这也正是Git所带给我们的,掌控历史进程的能力。下面就让我们一起来学习这个强大的工具吧。

一、Git是什么?
Git 是一个开源的分布式版本控制系统。 在项目开发中,开发人员通过 Git 追踪和协调他们代码的变化,以及将其历史版本记录下来,方便在需要时通过查阅历史版本进行问题的定位和修复。

二、为什么使用Git?

版本控制是软件开发的重要组成部分,对于代码更改的追踪和管理都显得至关重要。
Git不仅可用于版本控制,同时也是优秀的协作工具。当多名开发者同时工作在同一个项目中时,Git能够确保代码的同步并避免代码冲突。
此外,Git的存储效率和性能也非常高,能够快速地处理大量的操作和数据。

三、常用Git命令

接下来,我将一一介绍Git中常用的命令。

1.新建与配置


通过以下命令,可以新建一个Git代码仓库,也能够从网络上下载已有的项目:
  • git init 在当前目录新建一个Git代码库。
  • git clone [url] 下载一个项目及其整个代码历史。
Git的设置存储在.gitconfig文件中,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。以下命令可以用于显示及编辑设置:
  • git config --list 显示当前的Git配置。
  • git config -e [--global] 编辑Git配置文件。

2.增加与删除文件

增加或删除文件是日常工作中不可或缺的一部分,以下命令可帮助你完成这些工作:
  • git add [file1] [file2] ...:用于将指定文件添加到暂存区。你可以一次添加多个文件,只需要在 git add 后面列出文件的名字即可。
  • git add [dir]:此命令用于将指定目录(包括子目录)的所有文件添加到暂存区。
  • git add .:此命令用于添加当前目录的所有文件到暂存区。
  • git rm [file]: 此命令用于删除工作区的文件,并且将这次删除添加到暂存区。
  • git rm --cached [file]:此命令用于删除版本库的文件信息,但保留工作区的文件。这通常用于文件已经被纳入版本控制,但你希望忽略它们。例如,当你不小心将不需要提交的文件(比如包含敏感信息的配置文件)添加到了版本库,你需要移除版本库中的该文件,但在本地保留。这时,你可以使用 git rm --cached [file] 命令,接着在 .gitignore 文件中添加对应要忽略的文件名,防止今后误提交。

3.代码提交

与代码相关的修改,都应通过以下命令提交到Git仓库中:
  • git commit -m [message] 提交暂存区到仓库区。
  • git commit [file1] [file2] ... -m [message] 提交暂存区的指定文件到仓库区。
  • git commit --amend -m [message] 使用新的commit,替代上一次的提交。
  • git commit -a: 自动把所有已经跟踪过的文件的更改(新增、修改、删除)都放到暂存区,然后执行一次 commit。
  • git cherry-pick <commit-hash> 将特定的提交从一个分支应用(或称挑选)到另一个分支,生成新的【hash值不同的】提交。用于想要在不同的分支上修复同一个 bug,或者想要在主分支上迅速应用一个特性分支上的某个提交

4.分支新建与切换

在涉及多个开发人员或者需要同时进行多项任务时,分支是一种非常实用的功能。
  • git branch:这个命令用于查看本地所有的分支。
  • git branch -r:查看远程所有分支。
  • git branch [branch-name]:新建一个分支,但仍停留在当前分支。
  • git checkout -b [branch-name]:新建一个分支,并切换到该分支。
  • git checkout <branch-name> :将当前的工作目录切换成 <branch-name> 分支的代码。
  • git switch <branch-name> :将当前的工作目录切换成 <branch-name> 分支的代码。(checkout 命令和撤销修改相关,容易混淆,建议使用 Switch) 

5.分支合并

  • git merge [branch]:将指定分支合并到当前分支。
  • 无冲突git merge xxx快速合并
  • 有冲突CONFLICT (content): Merge conflict in readme.txtAutomatic merge failed; fix conflicts and then commit the result.Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,需要修改后提交:
  • $ git add readme.txt
  • $ git commit -m "conflict fixed"
  • 用带参数的git log也可以看到分支的合并情况:$ git log --graph --pretty=oneline --abbrev-commit
  • 当你合并两个分支时,如果一个分支是另一个分支的直接祖先,Git会默认使用 "Fast-forward" 的方式将二者合并,即直接将指针向前移动。但如果它们的历史不完全一样,Git 会进行 "three-way merge",并自动创建一个新的 commit。
  • git merge --abort 取消正在进行的合并; 
  • git reset --hard [commit] 将整个分支回滚到合并前的状态。【取消合并的一种方法】
  • git rebase [branch]: 整合到特定分支。这将以特定分支为基础,应用当前分支上的每一个commit。这种策略用于你想使你的工作分支基于最新的develop或master。
  • git rebase --continue: 解决完rebase冲突之后继续rebase。和merge类型,当rebase过程中出现冲突时,需要手动解决冲突。
  • git rebase --abort: 取消当前进行的rebase操作,返回操作前的状态

Git Merge:

  1. - 通过创建一个新的提交来集成两个分支的更改,新的提交在提交历史中有两个父提交。
  2. - 提交历史会包含所有的分支和合并操作,可能会显得比较复杂。
  3. - 在解决合并冲突时,只需解决一次冲突,然后创建一次合并提交。

Git Rebase:

  1. - 通过在目标分支上重新应用当前分支的每一个提交来集成更改,这样可以得到一个线性的提交历史。
  2. - 提交历史较为干净整洁,因为所有的更改都在一条直线上。
  3. - 在解决合并冲突时,可能需要在应用每个分支提交时处理冲突,这可能导致冲突解决的过程比较繁琐。

6.标签操作

在大型项目中,使用标签(tag)来标记特定的提交点,如新的版本发布点,是一种很好地实践。
  • git tag:列出所有的标签。
  • git tag [tag]: 在当前最新的提交上打一个新标签。
  • git tag [tag] [commit-id]: 在指定的提交上打一个新标签。
  • git tag -d [tag-name]:删除本地的一个标签。

7.查看信息

Git 提供了丰富的命令来帮助你查看项目的状态和历史记录:
  • git status:显示当前工作区的状态,让你能看到哪些更改被暂存,哪些更改未被暂存,以及哪些文件未被 Git 追踪。
  • git log: 显示当前分支的提交历史。git log --oneline 在一行内展示
  • git log --stat: 在git log基础上,显示每次提交修改过的文件
  • git log -p:查看每次详细的提交差异。
  • git diff: 此命令显示尚未暂存的改动对比,如果在 git diff 后面跟上文件名,可以查看指定文件的改动。如果在 git diff 后面跟上分支名,可查看当前工作区与对应分支的差异。
  • git diff --cached 或 git diff --staged : 显示已经暂存但尚未提交的改动。

8.远程同步

当你在团队中工作,或者想将你的项目发布到网络上时,你需要和远程的仓库进行交互。
  • git fetch [remote]: 下载远程仓库的所有变动。并不会将远程的变动合并到你的本地代码,也不会修改你现在正在工作的代码。
  • git pull [remote] [branch]: git fetchgit merge的结合,它将下载远程代码并直接合并到本地。
  • git push [remote] [branch]: 将你的改动上传到远程仓库,其他人才可能看到你的改动。
  • git branch --set-upstream [branch[remote-branch] :在现有分支与指定的远程分支之间建立追踪关系。
  • git push --force [remote] [branch]: 将本地分支强制推送到远程仓库,即使远程版本更新,但需谨慎,可能删除他人的提交。
  • 2. git fetch --all / git fetch --prune: --all使所有关联的远程仓库获取所有的分支。--prune更新本地仓库,删除已被远程删除的分支。

9.撤销操作

我们工作中,总是会存在想撤销某些操作的情况,Git 提供了撤销操作的命令:
  • git checkout -- [file]:撤销工作区的改动,将文件恢复到最近一次 commit 或者 add 的状态。
  • git reset [file]:会撤销已经暂存的文件,但并不会撤销工作区的修改。
  • git revert [commit-id]:撤销指定的提交,具体来说,它会创建一个新的提交,该提交的内容与需要被撤销的提交相反。
  • git reset [commit]或者 git reset --soft [commit] 撤销所有 [commit] 后的的提交,在本地保存更改

  • git reset --hard [commit] 立刻撤销所有指定commit之后的提交,并且清除工作区的所有修改,使得当前状态反映的是指定commit时的状态

  • 使用带有commit-id的命令时(如 git revert [commit-id],git reset --hard/soft [commit]),commit-id必须是存在的才有效,你可以通过 git log 来查看所有的提交记录和相应的commit-id。

  • 在使用这些命令时请慎重,确保知道这些命令的作用,因为一些操作在完成之后无法返回。

10.其他

有时一些文件最好不要用 Git 跟踪。这通常在名为 .gitignore 的特殊文件中完成。你可以在 github.com/github/gitignore 找到有用的 .gitignore 文件模板。

 

总结

 

  • 每一次填写完对应 "跳转命令" 后,当前的工作环境就会改变。比如说,当你执行 `git add <file>` 后,指定的文件就会被添加到暂存区,当你执行 `git commit -m 'message'` 后,暂存区的所有改动就会被提交到版本库。
名称描述跳转命令
Workspace 工作区 当前正在工作的目录,包含了你可以看到和编辑的文件。 文件的任意修改
Index / Stage 暂存区 保存了下次将提交的文件列表信息,记录了文件的变更信息。 git add <file/directory> 将修改添加到暂存区
Repository 版本库 存储了所有的管理信息,包括各个版本的提交信息,记录了项目的版本变更历史。 git commit -m 'message' 提交暂存区的改动到版本库
Remote远程仓库 在团队中工作,或者想将你的项目发布到网络上时使用

git push <remote><branch> 推送本地仓库到远程分支, 

git pull <remote><branch> 从远程拉取内容到本地

stash区 临时保存工作进度的地方,不影响工作区和版本库状态。 git stash 存储当前进度,git stash pop/apply 恢复之前的进度

本文只是浅尝辄止地了解了一些 Git 的命令,Git 仍有许多强大的功能等待我们去发掘。无论你处于何种程度,希望这篇文章可以帮助你更好地理解和使用 Git。
 
参考
https://www.runoob.com/wp-content/uploads/2015/02/011500266295799.jpg
https://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
https://training.github.com/downloads/zh_CN/github-git-cheat-sheet/