Git工作区
- Git仓库
最终确定的文件保存到仓库,成为一个新的版本,并且对他人可见。
- 暂存区(索引)
暂存已经修改的文件最后统一提交到git仓库中。
- 工作区
添加、编辑、修改文件等工作。
Git操作流程
- 初始化一个新的Git仓库
//创建文件夹test
mkdir test
//在文件夹内初始化Git仓库
cd test
git init //执行此命令后,会生成.git隐藏文件夹,用来存储所有git信息
- 向仓库提交文件
//我们先在test里写个aa文件
touch aa.txt
我们用 git status查看一下状态,文件是红色的,说明该文件还在工作区。
//将工作区的文件提交到暂存区
git add . //将所有文件夹添加到本地暂存区
git add 文件 //将指定文件添加到本地暂存区
此时查看状态,文件为绿色,表示已经在暂存区了。
//将本地暂存区代码提交到当前分支
git commit -m "添加代码"
提交到当前分支之后,再查看状态,已经是nothing to commit了,查看提交记录,可以看到有一次提交的信息。
- 修改文件
不管是我们修改还是删除添加文件,只要我们进行了新的操作,想提交到当前分支的话,都要经过上面那一系列操作,也就是先添加到暂存区,再提交到分支。
- 提交到远程仓库
上面所有的操作都是在本地,那么怎么把本地代码同步到远程仓库呢?先commit到本地分支后,再push到远程。
git push origin 远程分支名
//如果远程仓库没有这个分支,会自动创建的。
这里我们是在本地先建的仓库,再提交的。实际中可能是先把远程仓库的代码clone到本地。
//在你想复制到的目录下执行clone操作
git clone 仓库地址
其它命令
- git remote -v
查看指向的远程仓库的地址
- git branch -a
查看分支,红色的是远程分支,带星号的是当前的本地分支。
撤消
- git commit --amend
这个命令操作会让你重新修改上一次的提交附带信息,并且将目前暂存区的代码也提交,并且会覆盖上一次的提交(上一次的提交记录消失)。这个命令我感觉提交信息写错了可以用。
- 暂存区的文件撤回
git reset HEAD 文件名带后缀
- 撤回工作区的文件
就是你改了某个文件,觉得不多,下面命令可以让你获取到上一次commit的这个文件,直接覆盖掉当前这个文件。注意的是这个文件得是在工作区。提交到了暂存区是不行的。
git checkout -- 文件名带后缀
- commit之后的撤回
下面以撤回一次为例。
方式1: git reset --soft HEAD~
这种方式本质上是撤销了上一次 git commit 命令,上一次commit的内容还在暂存区。
如果撤回到某个提交: git reset --soft 路径
通俗点来说:
之前工作区的代码:还在
之前暂存区的代码:还在暂存区
已提交的代码:该路径(提交对象)下的代码就是最新的代码,包括之后的代码。
方式2: git reset --mixed HEAD~
它依然会撤销一上次 提交,但还会 取消暂存 所有的东西。
于是,我们回滚到了所有 git add 和 git commit 的命令执行之前。
如果撤回到某个提交: git reset --mixed 路径
通俗点来说:
之前工作区的代码:还在
之前暂存区的代码:变成工作的代码
已提交的代码:该路径(提交对象)下的代码就是最新的代码,包括之后的代码。
方式3:git reset --hard HEAD~
这个命令是非常危险的。撤销了最后的提交、git add 和 git commit 命令以及工作目录中的所有工作。
如果撤回到某个提交: git reset --hard 路径
通俗点来说:
之前工作区的代码:还在
之前暂存区的代码:消失
已提交的代码:该路径(提交对象)之后的代码消失
多个分支的管理
- 查看本地所有分支(当前分支绿色且带星号)
git branch
当前我们只有一个master分支。
- 本地新建分支branch1
git branch branch1
这个命令是在当前所在的提交对象上创建一个指针,也就是这个分支指向最后一次commit。所有此时有两个分支指向最后一次提交对象。但是当前分支不变,并没有切到这个新分支上。
也就是说,我们此时继续在当前分支master修改文件再commit,刚才那个branch1分支还是依然指向刚才那次提交。
- 切到新分支
git checkout branch1
这时我们已经切到新分支了,可以在上面开发,再commit。
- 合并
这个问题就比较复杂一点了,我们切回master分支重新操作。这里我们先写一个cc.txt,内容是:上线啦。commit到当前分支。
在当前,假如要开发新功能,所以要新建分支branch2来开发,在该分支下新建dd.txt。但是开发过程中我们上线的版本出了bug,所以要切回到master。要注意的是一定要把branch2写的代码commit,不然会出现不可预期的结果。
好了,切回到master后,开分支q12来处理bug。
这时候我们改完了bug,要合并到master分支去了。先切回master再合并。
由于当前 master 分支所指向的提交是你当前提交(有关 q12 的提交)的直接上游,所以 Git 只是简单的将指针向前移动。 换句话说,当你试图合并两个分支时,如果顺着一个分支走下去能够到达另一个分支,那么 Git 在合并两者的时候,只会简单的将指针向前推进(指针右移),因为这种情况下的合并操作没有需要解决的分歧。
此时master被快进到q12,和q12一起都指向了b5d31f1这个提交对象。这时候我们就不再需要q12了,可以删了这个分支。
git branch -d q12
如果branch2分支开发完了,我们也要合并到master。
这和之前合并q12分支的时候看起来有一点不一样。 在这种情况下,开发历史从一个更早的地方开始分叉开来(ec06f8e)。 因为,master 分支所在提交并不是 branch2 分支所在提交的直接祖先,Git 不得不做一些额外的工作。 出现这种情况的时候,Git 会使用两个分支的末端所指的快照(b5d31f1 和 68ce7ac)以及这两个分支的共同祖先(ec06f8e),做一个简单的三方合并。合并的结果做了一个新的快照并且自动创建一个新的提交指向它。
常见问题
- fatal: No configured push destination.
没有设置远程仓库地址,所有push的时候出问题。
git remote add origin https://github.com/gxh-apologize/test.git
需要说明的是,这个origin是远程仓库的默认名字,没有特殊的含义,尽管真实仓库名不是这个,但是我们没有特别指定的话,git默认就是origin。
- fatal: The current branch master has no upstream branch.
本地的分支没有和远程的分支关联起来,很可能只是执行了git push,git不知道push的目标分支。
git push --set-upstream origin master
- HEAD是什么?
HEAD 是当前分支引用的指针,它总是指向该分支上的最后一次提交。 这表示 HEAD 将是下一次提交的父结点。
说明
本文的初衷是为了简单快捷了解使用git,所以可能存在一些不严谨表述。如果需要更详细了解git,还请翻阅