git
Git 常用命令
git init 初始化仓库
在用户主目录下创建gitTest目录,在目录中打开Git Bash
输入命令 git init ,将当前目录初始化为一个git本地仓库(repository / repo)。
gitTest目录中多出的隐藏目录.git(版本库), 通过.git目录中的数据(包括各类git对象)对gitTest目录中的文件和目录内容进行版本管理。
git status 查看仓库状态
在gitTest目录新建文件file1
在bash中输入命令 git status
on branch master: 当前处在master分支(branch)
No commits yet:还没有提交(commit)
Untracked files:未跟踪(Untracked)的文件
git add 把要提交的变更加入到暂存区
跟踪新文件:未跟踪文件 -> 已跟踪文件
暂存已跟踪且提交后修改(Modified)的文件
底层做了两件事:创建新内容文件对应的git对象,更新索引文件.git/index (暂存区)
git commit -m “xxx” 创建提交
将所有加入暂存区的变更作为一个变更集合,创建提交。
-m “XXX” 提交时必须添加说明,记录做了哪些变更
每个commit都有一个唯一的哈希吗对应,可以把一个commit看成是项目的一个副本(snapshot) / 版本(Version)。而缓存区中存放的总是预期的下一次提交的快照。
在整个项目的开发过程中,会创建很多commit,这就相当于在开发过程中记录了多个版本,可以回退到过去的任何一个版本
git log / gitk 查看提交记录
在目录中新建文件file2,并修改file1的内容。
git add . && git commit && git log --oneline
git branch 创建分支
git branch b1:创建b1分支,底层做的事情:创建一个指向当前提交对象的一个指针b1。
-d : 删除分支,git branch -d b1
-a : 查看所有分支
git checkout 分支名称: 切换分支
当前分支:某一时刻,Git仓库总处于某一个分支下,即为当前分支,会有一个特殊的指针HEAD,指向当前分支。
git checkout b1:切换到b1分支,HEAD指针会指向b1分支,工作空间中的内容会恢复成b1分支最后一次提交时的样子。
git checkout -b b2:如果分支b2不存在,则创建分支b2,然后再切换到分支b2
git merge 分支名称: 合并分支
通常是在要开发一个新的功能模块时,或者是修复一个原有Bug时会创建对应的分支。当某个分支上的任务完成后,会将该分支中所有的更改“合并”(merge)到主分支上。
git merge b1:将b1分支上更改的内容合并到当前分支。
在b1中修改file1后提交,然后将b1分支合并到master分支。
git merge 命令选项
每次执行git merge命令时,git都会先去尝试能不能使用”Fast-forward”的模式进行合并,如果能,就默认使用”Fast-forward”的模式进行合并,如果不能,就创建一个合并提交进行合并。
git merge --no-ff:指定不使用快进模式进行合并
git merge --ff-only:指定只有能使用快进模式时才合并
git merge --no-edit:在创建合并提交之前不会调用编辑器,采用默认注释“Merge branch ‘BranchName’ ”
git merge --no-commit:合并后不自动提交,可以将内容进行进一步修改后。
注意:如果git默认编辑器是vim,可以在合并时弹出的编辑器界面输入 “:wq”,保存退出合并提交的界面。
解决合并冲突
如果两个分支中的同一个文件中的同一行的内容不一样,当我们合并这两个分支时,就会出现冲突。此时需要人为介入。
新建test分支,在test分支中修改file1并提交,切换到master分支,在master分支中也修改file1并提交。
此时将test合并到master时就会出现冲突。master分支就会处于合并中(MERGING)状态,需要“git merge --abort”放弃合并,或者修改file1文件后重新提交。
Current Change:当前分支中的内容放在 “<<<<<<< HEAD” 与 “=======” 之间。Incoming Change:被合并分支的内容放在 “=======” 与 “<<<<<<< 分支名” 之间。
修改冲突文件后保存并提交
版本回退
git reset 版本回退 :第一步移动 HEAD(--soft)
仓库中有一个file.txt文件,先后经过了3次修改提交
现使用命令 git reset --soft HEAD~ | HEAD^ 回退一次
结论:只移动分支和HEAD指针,工作区和暂存区的内容不变。即回滚到了上一次commit之前的状态。
第二步更新索引
仓库中有一个file.txt文件,先后经过了3次修改提交
现使用命令 git reset HEAD~ | HEAD^ 回退一次
结论:移动分支和HEAD指针,取消上次暂存的内容,工作区内容不变。即回滚到了上一次commit和add之前的状态。
第三步更新工作区(--hard)
仓库中有一个file.txt文件,先后经过了3次修改提交
现使用命令 git reset --hard HEAD~ | HEAD^ 回退一次
结论:移动分支和HEAD指针,取消上次暂存的内容,使工作区和暂存区内容一致。即回滚到了上上一次commit之后的状态
git reset 版本回退 :
修改file1的内容提交
使用git reset --hard HEAD^ 回退一次提交
回退后,查看file1的内容,和commit记录。
如果此时恢复上次提交的话, 要用 git reflog命令查看上次提交的ID,然后用 git reset --hard commitID,回到“未来”的版本。
如果此时恢复上次提交的话,要用 git reflog 命令查找上次提交的ID,然后用 git reset --hard commitID,回到“未来”的版本。
克隆远程仓库
git clone 克隆远程仓库
cd ~:切换到用户主目录
克隆远程仓库 git clone 远程仓库地址
cd 代码目录
git clone 默认会建立与远程仓库(默认名origin)的关联,并把远程仓库中所有的内容都复制到本地仓库,并建立本地仓库和远程仓库的关联,会创建本地仓库分支master,并与远程仓库分支master的进行关联(Trace)。
git remote -v :查看远程仓库信息
master:本地仓库分支;remotes/origin/master:本地仓库远程分支;origin/master:远程仓库分支
初始时,这三个Branch指向同一个Commit
推送更新
git push 推送更新
本地仓库创建文件file1并提交。
本地仓库分支和本地远程仓库分支 指向的是不同的Commit。
执行命令:git push origin master:master 或者 git push
推送本地master分支后,本地仓库工作区和版本库的内容推送到了远程仓库,三个分支指向同一个Commit。
本地仓库创建新的分支feature1
git push --set-upstream origin feature1:feature1
将本地仓库的feature1分支推送到远程仓库,远程仓库中也会创建对应的feature1分支,同时本地仓库的feature1分支会和远程仓库的feature1分支建立关联。
拉取远程分支
git fetch 拉取更新
在本地仓库test1的feature1分支中更新推送。
在本地仓库test2中通过git fetch拉取远程仓库中最新的内容(上次fetch后,推送到远程仓库的所有更新),但只会将数据下载到你的本地仓库,不会自动合并到对应的本地分支(本地仓库分支未修改),不会修改本地仓库的工作区、暂存区。
git fetch命令只是把远程仓库的数据拉取到本地仓库,并不会更新本地仓库对应的分支,如果需要更新本地仓库分支,需用要git merge命令合并对应的远程仓库。
git pull = git fetch + git merge 拉取更新后合并
在本地仓库test1的feature1中再次更新推送。
在本地仓库test2的feature1分支下中通过git pull拉取远程仓库中最新的内容,并自动将远程分支origin/feature1合并到本地仓库feature1分支。
查看远程仓库
git remote 设置查看远程仓库
-v : 查看远程仓库信息, origin 默认远程仓库名称
rm 远程仓库名称: 删除远程仓库
add 远程仓库名称 远程仓库地址: 添加远程仓库