0.基础准备
0.0 vscode
vscode下载链接:https://code.visualstudio.com/Download
按部就班的下载完毕vscode后,安装相应的Cpptools工具
0.1 minGW
MinGW,是Minimalist GUN for Windows的缩写。它是一个可自由使用和自由发布的Windows特定头文件和使用GNU工具集导入库的集合,允许你在GNU/Linux和Windows平台生成本地的Windows程序而不需要第三方C运行时(C Runtime)库。
MinGW下载地址:https://sourceforge.net/projects/mingw-w64/files/
下载完毕后,还需配置环境变量,可以在cmd下键入gcc看是否成功配置环境。
0.2 配置C++环境
进入vscode,新建一个cpp文件,键入以下代码:
1 #include <stdio.h>
2 #include <windows.h>
3 int main()
4 {
5 printf("Hello World\n");
6 system("pause");
7 return 0;
8 }
此时代码尚无法运行,笔者在此处两个头文件下方都有波浪线显示错误。使用CTRL+shift+D进入调试界面,添加配置环境,选择 C++(GDB/LLDB),再选择 g++.exe,之后会自动生成 launch.json 配置文件,修改配置文件的路径(如"miDebuggerPath"等项应该为你的环境下的路径),之后会有tasks.json文件的修改,形式也是同理的。
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) 启动",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": true,
"MIMode": "gdb",
"miDebuggerPath": "F:\\minGW\\mingw64\\bin\\gdb.exe",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "task g++" //修改此项
}
]
}
一切修改结束后,再按下F5发现没有报错,程序顺利通过。
0.3 建立远程仓库
注册GitHub账号后,可以在your repositories中新建一个数据仓库
至此,基本准备工作已经就绪。
1.Git本地库基础用法
1.1 初始化本地库
在基本工作准备阶段,我们已经在GitHub上面建立了远程仓库,所以这里我们只需要打开相应的路径,通过git语句将远程仓库的文件克隆下来即可。
git clone https://github.com/Whuzjc/git_test
如果没有在GitHub上建立仓库,也可以用如下语句建立本地库
git init
1.2 本地版本库基本操作
Git的本地库只涉及上图的红圈部分。本地仓库由gi维护的三棵树组成,分别为工作目录(workspace),暂存区(index)和存储库(repository),这三棵树构成了本地闭环版本库。在本地库操作中,你可以对当前版本文件提出更改,并将这些更改放在暂存区(也就是图中所示的workspace执行add操作,将文件放入index中),命令如下所示:
git add <filename>
git add *
这是git基本工作流程的第一步,使用如下代码可以进行实际的提交改动(即图中的执行commit指令,将index文件提交至repository):
git commit -m "代码提交信息"
这样就可以将改动提交到了HEAD[3]。使用reset指令可以删除在index中的文件:
git reset [--soft | --mixed | --hard] [HEAD]
--mixed 为默认,可以不用带该参数,用于重置暂存区的文件与上一次的提交(commit)保持一致,工作区文件内容保持不变。--soft 参数用于回退到某个版本。--hard 参数撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到上一次版本,并删除之前的所有信息提交。
1.3 实际操作
下面我们将在实际操作一下。
在本地库中添加jump.cpp文件
1 #include<iostream>
2 #include<vector>
3 #include<windows.h>
4 using namespace std;
5 int jump_ans(int N){
6 if(N==1||N==0) return 1;
7 else return jump_ans(N-1)+jump_ans(N-2);
8 }
9 int main(void){
10 int N,ans;
11 cout << "input the number of steps:" <<endl;
12 cin >> N;
13 ans=jump_ans(N);
14 cout << "the methods to reach order "<< N<< " are as follow:"<< ans <<endl;
15 system("pause");
16 return 0;
17 }
此时我们可以使用git status指令查看当前状态:
PS C:\Users\ASUS\Desktop\git_test\git_test> git status
On branch master
Your branch is up to date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
jump.cpp
jump.exe
nothing added to commit but untracked files present (use "git add" to track)
在git status指令下可以看到当前分支,且存在两个尚未确认的文件jump.exe和jump.cpp(因为是c++代码,生成一个.exe文件)。此时我们可以使用git add指令将文件提交到index下面后,再次执行git status指令:
PS C:\Users\ASUS\Desktop\git_test\git_test> git add jump.cpp
PS C:\Users\ASUS\Desktop\git_test\git_test> git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: jump.cpp
Untracked files:
(use "git add <file>..." to include in what will be committed)
jump.exe
在执行了git add指令后,似乎什么也没有发生,但是执行了git status后,可以看到明显的区别:jump.cpp文件已经被提交至index,但是jump.exe还未被确认。既然将文件添加到了暂存区index,也可以使用reset指令将其删除,实机演示如下:
PS C:\Users\ASUS\Desktop\git_test\git_test> git reset HEAD jump.cpp
PS C:\Users\ASUS\Desktop\git_test\git_test> git status
On branch master
Your branch is up to date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
jump.cpp
jump.exe
nothing added to commit but untracked files present (use "git add" to track)
然后我们再试着将jump.cpp提交到本地版本库,使用commit指令即可:
PS C:\Users\ASUS\Desktop\git_test\git_test> git add jump.cpp
PS C:\Users\ASUS\Desktop\git_test\git_test> git commit -m "1th time"
[master ff3b3b4] 1th time
1 file changed, 17 insertions(+)
create mode 100644 jump.cpp
PS C:\Users\ASUS\Desktop\git_test\git_test> git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
Untracked files:
(use "git add <file>..." to include in what will be committed)
jump.exe
nothing added to commit but untracked files present (use "git add" to track)
可以看到,jump.cpp成功提交到了本地库,至此基本的本地操作均已实现。
2.Git远程版本库的基本用法
远程版本库的操作就涉及上图中的push、pull和clone操作(clone已经实现过操作,这里不再赘述),即使用push操作,可以将当前的本地版本库送到远程版本库中,也可以使用pull操作将远程服务器上的文件下载到本地的workspace中。
使用push指令后:
PS C:\Users\ASUS\Desktop\git_test\git_test> git push
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 535 bytes | 535.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/Whuzjc/git_test.git
1c95411..ff3b3b4 master -> master
在终端可以看到完成了相关的文件传输工作,此时打开浏览器上GitHub,也可以看到在远程的版本库上也存在了我们上传的jump.cpp。
然后再新建一个文件夹名为git_test2,使用git pull指令将远程的代码下载到本地库:
PS C:\Users\ASUS\Desktop\git_test2> git pull
Cloning into 'git_test'...
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 7 (delta 1), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (7/7), done.
可以看到,内容与远程库的文件信息一致
3.团队项目中的分支合并
3.1 分支合并操作
几乎每一种版本控制系统都以某种形式支持分支。使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作,所以有人把 Git 的分支模型称为必杀技特性,而正是因为它,将 Git 从版本控制系统家族里区分出来。下面我们来看一下git中涉及的分支指令操作。[5]
创建分支命令:
git branch (branchname)
切换分支命令:
git checkout (branchname)
合并分支命令:
git merge
3.2 操作流程
一般来说,分支合并操作的流程可以按照如下四步:
(1)克隆或同步最新的代码到本地存储库;
(2)为自己的工作创建一个分支,该分支应该只负责单一功能模块或代码模块的版本控制;
(3)在该分支上完成某单一功能模块或代码模块的开发工作;
(4)最后,将该分支合并到主分支。
3.3 实际操作
(1)创建分支
使用git checkout指令创建了mybranch分支,同时完成了分支的切换,如下所示:
PS C:\Users\ASUS\Desktop\git_test\git_test> git checkout -b mybranch
Switched to a new branch 'mybranch'
PS C:\Users\ASUS\Desktop\git_test\git_test> git branch
master
* mybranch
(2)修改分支文件
在master分支中,我们采用了递归的方法求解,此处我们将jump_ans函数修改为使用动态规划的方法来求解。
int jump_ans(int N){
vector<int> dp;
for(int i=0;i<=N;i++){
if(i==1||i==0) dp.push_back(1);
else dp.push_back(dp[i-1]+dp[i-2]);
}
return dp[dp.size()-1];
}
(3)在分支mybranch上提交
PS C:\Users\ASUS\Desktop\git_test\git_test> git add jump.cpp
PS C:\Users\ASUS\Desktop\git_test\git_test> git status
On branch mybranch
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: jump.cpp
Untracked files:
(use "git add <file>..." to include in what will be committed)
jump.exe
PS C:\Users\ASUS\Desktop\git_test\git_test> git commit -m "2th time"
[mybranch 637e04d] 2th time
1 file changed, 6 insertions(+), 2 deletions(-)
(4)合并
切换回到master分支,下载远程版本库的文件,然后使用merge指令实现master和mybranch的合并,最终将合并的结果上传到远程版本库,终端结果如下所示:
PS C:\Users\ASUS\Desktop\git_test\git_test> git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
PS C:\Users\ASUS\Desktop\git_test\git_test> git pull
Already up to date.
PS C:\Users\ASUS\Desktop\git_test\git_test> git merge --no-ff mybranch
Merge made by the 'recursive' strategy.
jump.cpp | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
PS C:\Users\ASUS\Desktop\git_test\git_test> git push
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 479 bytes | 479.00 KiB/s, done.
Total 4 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 2 local objects.
To https://github.com/Whuzjc/git_test.git
ff3b3b4..f691045 master -> master
在GitHub上查看network,如下图所示:
4.Git Rebase
4.1 Git Rebase概念
git rebase 算是git里的高级操作了,他主要用来解决两种情况。
(1)有时候我们对于一个简单的需求提交了多次,这样非常不利于code review,所以我们需要将多次提交合并成一次提交。(即多次commit合并成一次commit)
(2)你从master创建一个分支开发,然后你的同事又从master创建一个分支开发,但是他比你先提交,所以远程的master分支比你的本地master走的远,所以现在要将你的分支代码基于远程的master来实现提交。[5]
4.2 实际操作
使用git rebase指令,可以看到进入了一个命令行的文本编辑器:
PS C:\Users\ASUS\Desktop\git_test\git_test> git rebase -i
pick ff3b3b4 1th time
pick 637e04d 2th time
# Rebase 1c95411..637e04d onto 1c95411 (2 commands)
#
# Commands:
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
删掉第一行“pick ff3b3b4 1th time”,保存并退出,会发现出现错误:
PS C:\Users\ASUS\Desktop\git_test\git_test> git rebase -i HEAD^^
CONFLICT (modify/delete): jump.cpp deleted in HEAD and modified in 637e04d... 2th time. Version 637e04d... 2th time of jump.cpp left in tree.
error: could not apply 637e04d... 2th time
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 637e04d... 2th time
即存在冲突,当修改完成后解决冲突,就可以继续使用add,commit等常规操作。此时查看git log,可以看到原先的两个版本变成了一个版本。
PS C:\Users\ASUS\Desktop\git_test\git_test> git log
commit 1c954115b0c772da603e50cd8520b6bc42bd99d3 (HEAD -> mybranch)
Author: Dlzjc <35788413+Whuzjc@users.noreply.github.com>
Date: Thu Oct 8 16:04:33 2020 +0800
Initial commit
5.心得与体会
本文主要根据孟宁老师的五大场景玩转git一文,实现了在vscode上的git代码管理,对于git的使用有了一些感性和理性的认识,希望在今后的生活和工作中多多运用这一强有力的工具来武装自己。
本文暂时没有评论,来添加一个吧(●'◡'●)