Git开发必知必会
比如说你现在准备写一个自己的视频资源网站,在创业初期,你的项目暂时还是测试阶段,没有用户的时候,你可能只有一个人在开发,你每天都以写的内容和时间作为文件名的命名,这样其实是可以满足你对版本控制的基本需求的,唯一的问题是,当你要返回某个版本的时候你很难直接就找到你想要的那个状态,因为你可能有还几十个版本的文件,如果中途你的硬件坏了,比如磁盘文件丢失,这确实不是一个程序员想看到的状态。这个时候你可能需要一个分布式开发利器来帮你排忧解难了,所以我准备写点关于Git的博客。
首先你要知道的是,Git分为服务端与客户端,我们把每个版本的文件上传到远程仓库里,而且每次提交的信息都可以明确告诉你是那一版,接下来详细说一下怎么使用Git来协助开发。
首先要进行工作文件夹的初始化(就是给仓库进行装修,使仓库更便于管理)。初始化完成后,我们就不需要手动修改什么版本1,版本2了。。。我们每次上传的文件都被保留为一个版本。
比如说你现在准备写一个自己的视频资源网站,在创业初期,你的项目暂时还是测试阶段,没有用户的时候,你可能只有一个人在开发,你每天都以写的内容和时间作为文件名的命名,这样其实是可以满足你对版本控制的基本需求的,唯一的问题是,当你要返回某个版本的时候你很难直接就找到你想要的那个状态,因为你可能有还几十个版本的文件,如果中途你的硬件坏了,比如磁盘文件丢失,这确实不是一个程序员想看到的状态。这个时候你可能需要一个分布式开发利器来帮你排忧解难了,所以我准备写点关于Git的博客。
首先你要知道的是,Git分为服务端与客户端,我们把每个版本的文件上传到远程仓库里,而且每次提交的信息都可以明确告诉你是那一版,接下来详细说一下怎么使用Git来协助开发。
首先要进行工作文件夹的初始化(就是给仓库进行装修,使仓库更便于管理)。初始化完成后,我们就不需要手动修改什么版本1,版本2了。。。我们每次上传的文件都被保留为一个版本,并且每个版本都是经过压缩的,占的空间非常小。
$ git init Initialized empty Git repository in E:/test/.git/
现在我们创建开发视频项目,并将视频项目从工作区转到版本库中。
MINGW64 /e/test (master) $ git add '开发视频.txt' MINGW64 /e/test (master) $ git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: "\345\274\200\345\217\221\350\247\206\351\242\221.txt"
然后从版本库的暂存区转到分支。
MINGW64 /e/test (master) $ git commit -m '第一次视频上传' [master (root-commit) 9e5b463] 第一次视频上传 1 file changed, 1 insertion(+) create mode 100644 "\345\274\200\345\217\221\350\247\206\351\242\221.txt"
版本提交完成后,本地与分支的代码一致。
MINGW64 /e/test (master)
$ git status
On branch master
nothing to commit, working tree clean
添加一个新的论坛功能。
MINGW64 /e/test (master) $ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) "\350\265\204\346\272\220\350\256\272\345\235\233.txt" nothing added to commit but untracked files present (use "git add" to track)
此时的本地与版本库不一致,查看状态即可得知。我们需要二次上传。按照上述的提交次序进行版本更改后的提交。
MINGW64 /e/test (master) $ git add . MINGW64 /e/test (master) $ git commit -m '新开发了论坛功能' [master e87047a] 新开发了论坛功能 1 file changed, 1 insertion(+) create mode 100644 "\350\265\204\346\272\220\350\256\272\345\235\233.txt" MINGW64 /e/test (master) $ git status On branch master nothing to commit, working tree clean
此时,我们的版本库里就有两个版本的文件了。
查看分支都有哪些文件。
MINGW64 /e/test (master) $ git ls-tree head 100644 blob 1890c0533c72cc3b80d681d94a0f891d3f5378be "\345\274\200\345\217\221\350\247\206\351\242\221.txt" 100644 blob 8c46b0fcd2871597ebba639f61b101dfa495840b "\350\265\204\346\272\220\350\256\272\345\235\233.txt"
注:提交前需要配置个人信息,以便记录谁做了哪些操作。
MINGW64 /e/test (master) $ git config --global user.email "2609749420@qq.com" MINGW64 /e/test (master) $ git config --global user.name "jefflike"
没有配置相关的信息,在你提交的时候会报错,有了你的信息,git日志文件会记录你所做的事。
MINGW64 /e/test (master) $ git log commit e87047a9fe199360d2f0d97d912bf36a63274ff3 (HEAD -> master) Author: jefflike <2609749420@qq.com> Date: Fri Mar 16 10:18:03 2018 +0800 新开发了论坛功能 commit 9e5b463cc31fd946d78d78919c2f50b077ff14cf Author: jefflike <2609749420@qq.com> Date: Fri Mar 16 10:09:23 2018 +0800 第一次视频上传
commit后面的作为唯一标识,帮助我们回滚时使用。
比如现在由于相关规定,我们的论坛功能暂时要关闭一段时间,此时我们需要将我们项目回滚到第一次提交的状态。需要使用到9e5b463cc31fd946d78d78919c2f50b077ff14cf。
a2609@DESKTOP-3FO2EDL MINGW64 /e/test (master) $ git reset --hard 9e5b463cc31fd946d78d78919c2f50b077ff14cf HEAD is now at 9e5b463 第一次视频上传
直接回到论坛的版本未创建的状态,论坛文件都没有。
过了一段时间,我们的论坛又可以继续上线了,但是此时我们git log发现我们现在回滚到的版本里压根就没有创建过论坛的文件的信息。
MINGW64 /e/test (master) $ git log commit 9e5b463cc31fd946d78d78919c2f50b077ff14cf (HEAD -> master) Author: jefflike <2609749420@qq.com> Date: Fri Mar 16 10:09:23 2018 +0800 第一次视频上传
那该怎么办呢,从新写一个论坛模块吗?不存在的。
MINGW64 /e/test (master) $ git reflog 9e5b463 (HEAD -> master) HEAD@{0}: reset: moving to 9e5b463cc31fd946d78d78919c2f50b077ff14cf e87047a HEAD@{1}: commit: 新开发了论坛功能 9e5b463 (HEAD -> master) HEAD@{2}: commit (initial): 第一次视频上传 MINGW64 /e/test (master) $ git reset e87047a Unstaged changes after reset: D 资源论坛.txt MINGW64 /e/test (master) $ git status On branch master Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) deleted: "\350\265\204\346\272\220\350\256\272\345\235\233.txt" no changes added to commit (use "git add" and/or "git commit -a") MINGW64 /e/test (master) $ git checkout 资源论坛.txt
你在继续开发资源论坛开发到一半的时候,视频网站出现了bug急需修复,此时你该如何操作呢。
MINGW64 /e/test (master) $ git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: "\350\265\204\346\272\220\350\256\272\345\235\233.txt" no changes added to commit (use "git add" and/or "git commit -a")
MINGW64 /e/test (master)
$ git stash
Saved working directory and index state WIP on master: e87047a 新开发了论坛功能
将当前工作修改部分转移到分支,此时我们的论坛恢复到新功能开发之前的版本:
修复完bug要上传。
MINGW64 /e/test (master) $ git add . MINGW64 /e/test (master) $ git commit -m '修复bug' [master e384a95] 修复bug 1 file changed, 2 insertions(+), 1 deletion(-)
此时我们的项目又从新运行起来,没有bug,我们需要合并分支,把之前的功能拿回来。
MINGW64 /e/test (master) $ git stash pop On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: "\350\265\204\346\272\220\350\256\272\345\235\233.txt" no changes added to commit (use "git add" and/or "git commit -a") Dropped refs/stash@{0} (683d356c11ebf111412cfaa3ceb996b75dd402a2) MINGW64 /e/test (master) $ git add . MINGW64 /e/test (master) $ git commit -m '论坛活动开启' [master 02c4cfe] 论坛活动开启 1 file changed, 2 insertions(+), 1 deletion(-)
我们继续开发,合并分支后修改的bug保持被修改后的状态。
在这里可能存在冲突的情况,比如我的论坛开发到一半,我们需要将论坛的模板换掉,此时就存在了冲突。
老板说先把活动的主题换上。
主题换上继续开发未完成的活动。此时应有冲突出现:
MINGW64 /e/test (master) $ git stash pop Auto-merging 资源论坛.txt CONFLICT (content): Merge conflict in 资源论坛.txt
需要我们手动解决,并提交。
直接修改完并提交,我们的新项目在一路bug需求不断的情况下,非常顺利的完成了。
MINGW64 /e/test (master)
$ git status
On branch master
nothing to commit, working tree clean
至此,我们一个人开发项目不论遇到什么事,都可以顺利的解决掉。
上述问题我们一般会采用分支的方式来解决:
我们开发过程中一般会保留两个分支,即master(只保留线上版本)和dev(只保留开发版本)。
创建我们的开发版本和进入开发分支。
MINGW64 /e/test (master)
$ git branch
* master
MINGW64 /e/test (master) $ git branch dev MINGW64 /e/test (master) $ git checkout dev Switched to branch 'dev' MINGW64 /e/test (dev) $ git branch * dev master
我们在dev开发清明节抽奖活动。
开发到一半时,线上master出了大bug,急需修改。我们先要切换到主分支,创建bug分支解决bug合并到主分支。
MINGW64 /e/test (dev) $ git checkout master Switched to branch 'master' MINGW64 /e/test (master) $ git branch dev * master
线上版本是没有我们的新活动的。
MINGW64 /e/test (master) $ git branch bug MINGW64 /e/test (master) $ git checkout bug Switched to branch 'bug' MINGW64 /e/test (bug) $ git branch * bug dev master
主分支进行合并分支
MINGW64 /e/test (bug) $ git checkout master Switched to branch 'master' MINGW64 /e/test (master) $ git merge bug Updating 0dfcebc..360e6ca Fast-forward "\350\265\204\346\272\220\350\256\272\345\235\233.txt" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) MINGW64 /e/test (master) $ git status On branch master nothing to commit, working tree clean
最后删除bug分支
MINGW64 /e/test (master) $ git branch -d bug Deleted branch bug (was 360e6ca). MINGW64 /e/test (master) $ git branch dev
切换到开发分支直到开发完成。
此时分支的bug没有解决,因为这不是线上环境,有bug不用担心,我们线上已经解决了。开发完成与主分支合并。
MINGW64 /e/test (dev) $ git checkout master Switched to branch 'master' MINGW64 /e/test (master) $ git merge dev Merge made by the 'recursive' strategy. ...216\350\212\202\346\212\275\345\245\226\346\264\273\345\212\250.txt" | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 "\346\270\205\346\230\216\350\212\202\346\212\275\345\245\226\346\264\273\345\212\250.txt" MINGW64 /e/test (master) $ git branch dev * master
此时将线上分支与开发分支合并。新活动上线并且,bug也是修复成功后的状态。
这样就完成了多分支解决线上bug问题了。
我们现在的所有版本都在自己的主机上跑,实际生产环境是不可能的,我们可能会在多台不同的机器上开发同一个项目。这个时候我们需要一个远程仓库来供我们使用。
关联到远程仓库(首先在github上必须要有一个)
MINGW64 /e/test (master)
$ git remote add origin git@github.com:jefflike/git_test.git
MINGW64 /e/test (master) $ git push origin master The authenticity of host 'github.com (192.30.253.112)' can't be established. RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'github.com,192.30.253.112' (RSA) to the list of known hosts. Counting objects: 29, done. Delta compression using up to 8 threads. Compressing objects: 100% (23/23), done. Writing objects: 100% (29/29), 2.76 KiB | 353.00 KiB/s, done. Total 29 (delta 6), reused 0 (delta 0) remote: Resolving deltas: 100% (6/6), done. To github.com:jefflike/git_test.git * [new branch] master -> master
MINGW64 /e/test (master) $ git checkout dev Switched to branch 'dev' a2609@DESKTOP-3FO2EDL MINGW64 /e/test (dev) $ git push origin dev Total 0 (delta 0), reused 0 (delta 0) To github.com:jefflike/git_test.git * [new branch] dev -> dev
我们把分支提交到线上。
我们把代码放到仓库以后,电脑就可以扔掉了,那是不可能的。
回到家,打开自己的个人电脑,接着开发。第一件事就是从线上把代码拉下来
拉代码的两种方式
MINGW64 /e/Git_test (master) $ git pull new_origin dev remote: Counting objects: 24, done. remote: Compressing objects: 100% (16/16), done. remote: Total 24 (delta 2), reused 22 (delta 2), pack-reused 0 Unpacking objects: 100% (24/24), done. From github.com:jefflike/git_test * branch dev -> FETCH_HEAD * [new branch] dev -> new_origin/dev
直接一步把开发版本拉到本地工作区,后面的解决问题主要操作就是我们之前的合并分支所进行的操作一致。
建立本地的dev分支与线上一致。
MINGW64 /e/Git_test (master) $ git branch * master MINGW64 /e/Git_test (master) $ git branch dev new_origin/dev Branch 'dev' set up to track remote branch 'dev' from 'new_origin'. MINGW64 /e/Git_test (master) $ git checkout dev Switched to branch 'dev' Your branch is up to date with 'new_origin/dev'. MINGW64 /e/Git_test (dev) $ git branch * dev master
git删除远程仓库的分支方式
git branch -r -d origin/branch-name
git push origin :branch-name
root@debian:/home/jeff/git_java# git branch -r -d origin/day001 已删除远程跟踪分支 origin/day001(曾为 6f9e621)。 root@debian:/home/jeff/git_java# git push origin :day001 To github.com:jefflike/java_coding.git - [deleted] day001