版本管理工具Git:入门教程 | 您所在的位置:网站首页 › gitea模板 › 版本管理工具Git:入门教程 |
Git使用教程
目录Git使用教程1.简介2.安装与配置安装配置3.Git的区域概念4. 从远程创建一个新仓库①创建一个远程仓库②把远程仓库取到本地③尝试自己写个提交④再来个提交⑤把提交推送到远程仓库5.本地创建仓库并关联到远程仓库①在项目目录中新建一个仓库②创建一个空白的远程仓库③关联远程仓库④把本地提交推送到远程仓库6.HEAD、master、分支的本质HEAD:当前commit的引用分支(branch)master:默认分支branch 的通俗化理解7.创建、切换、合并、删除分支列出所有分支创建分支切换分支合并分支删除分支8.仓库的同步推送拉取合并冲突多人合作的基本工作模型9.Git的部分常用操作提交与修改git add --添加文件到暂存区git commit --提交暂存区到本地仓库git status --查看当前仓库的状态git diff --比较文件差异git rm --从暂存区删除文件git restore --恢复操作查看提交历史与回退版本git log --查看提交历史git blame --查看指定文件的修改记录git reset --回退版本git reset命令的用法:
1.简介
Git(读音为/gɪt/)是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。 也是[Linus Torvalds](https://baike.baidu.com/item/Linus Torvalds/9336769?fromModule=lemma_inlink)为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。 分布式相比于集中式的最大区别在于开发者可以提交到本地,每个开发者通过克隆(git clone),在本地机器上拷贝一个完整的Git仓库。 2.安装与配置 安装在Windows上使用Git,可以直接从Git镜像下载安装程序。 打开安装程序,按默认选项安装即可。安装完成后,可以在开始菜单中中找到Git Bash、 Git GUI 、 Git CMD这几个软件,能打开说明安装成功;或者在命令行工具(例如PowerShell、cmd),输入命令git,能打印出Git的使用帮助,说明安装成功。 安装完成后,为区别不同用户的提交记录,需要配置一下用户名和用户邮箱。使用命令行工具,输入命令并按下回车即可: git config --global user.name "Your Name" git config --global user.email "[email protected]"使用如下命令可以查看当前全局配置的用户名和邮箱: git config --global user.name git config --global user.email如果去掉--global,只在当前仓库生效。 3.Git的区域概念一个仓库拥有三个区,不同区拥有不同的功能。文件的提交流程是工作区->暂存区->版本库 工作区:就是工作目录。别名:工作树 暂存区:是 .git 目录下一个叫做 index 的文件,所以暂存区有时也被叫作索引(index)。暂存区是一个介于工作区和版本库的中间状态,通过 add 指令暂存的内容,都会被写进这个文件里,当执行提交时实际上是将暂存区的内容提交到版本库中。 版本库:就是本地仓库,它就是 .git这个文件夹。 访问使用gitea自搭建的远程仓库(也可以使用Github、Gitee等第三方Git托管服务,功能基本上都是一样的) 注册或者登录账号(注意:邮箱要和本地配置的邮箱相同) 点击右上角+号,创建一个远程仓库 进入仓库信息填写页面:1为仓库的名称,这个仓库名会被 Git 设置为你的仓库的根目录的名称;2为仓库的描述,远程仓库会根据描述信息生成一个README.md文件;3为选择一个.gitignore模板,用于设置不允许git跟踪的文件。然后点击最下方的创建仓库来完成创建远程仓库 刚创建完的仓库大概的样子: 点击复制右边的仓库地址(也可以点击下载按钮,直接把仓库压缩包下载到本地) ②把远程仓库取到本地接下来就可以把远程仓库取下来了。取的方式很简单:在 powershell 或 cmd 中切换到你希望放置项目的目录中,然后输入: git clone 远程仓库地址Git就会把远程仓库clone到本地。(第一次下载和推送之前,Git可能会要求输入远程仓库的账户名与密码。)下载完成之后,我们会看到,当前所在的目录下出现了一个子目录,它的名字与远程仓库的名字相同: 可以看到在.gitignore和README.md这两个文件之外,还有一个.git的隐藏文件夹。 这个 .git 文件夹,就是你的本地仓库(Local Repository),你的所有版本信息都会存在这里。而 .git 所在的这个根目录,称为 Git 的工作目录(Working Directory),它保存了你当前从仓库中签出(checkout)的内容。现在把命令行工具切换到git-manual目录下,输入: git log可以看到仓库的提交历史: 这时候只有一条提交历史,这个提交是远程仓库帮你做的,它的内容是创建你的初始 .gitignore 和 README.md 这两个文件。图中第一行中的 commit 右边的那一大串字符( ad30e8731......6175),是这个 commit 的 SHA-1 校验和(你可以暂时把它简单理解为这个 commit 的 ID,因为SHA-1是一种哈希算法,所以也叫它哈希值);后面括号里的内容(HEAD -> main ...)后续再说;第一行的下面,依次是这个 commit 的作者、提交日期和提交信息,其中提交信息记录了这个提交做了什么,是提交者填写的(当然,这条提交信息是 远程仓库 帮你写的)。 ③尝试自己写个提交把远程仓库取到本地之后,我们就可以开始写代码了。为了练手,我们可以随便创建一个文本文件,.c,.txt等格式都可以,这里新建一个text.txt文件,向里面添加一段文本。 Git的提交命令是commit,但是现在我们还不能直接提交,首先在命令行输入: git statusstatus用来查看工作目录当前的状态 这段文字表达的信息: 1.你当前在main分支 2.你的分支没有落后于origin/master 3.你有未追踪的文件,文件名是text.txt,如果你需要提交它,使用git add开始追踪文件。 由第三条可以看出,当前Git仓库对text.txt没有进行任何记录,对于Git仓库而言,text.txt是不存在的。所以,要想提交这个文件,需要先使用git add 让Git开始跟踪它的变化: git add text.txt执行完命令之后,git不会反馈成功的信息,这时候可以再次执行git status 可以看到,信息已经变化了,text.txt字体变成了绿色,前面多了new file:的标记,这些都说明一点:shopping list.txt 这个文件的状态从 "untracked"(未跟踪)变成了 "staged"(已暂存),意思是这个文件中被改动的部分(第一次添加就是这一整个文件)被记录进了 staging area(暂存区)。 现在文件已经进入了暂存区,就可以提交了。提交的方式是用commit指令: git commit -m "添加text.txt,并添加一些文字"这样就完成了一次提交,-m "添加text.txt,并添加一些文字"是为这次提交附加的提交信息,一般用于说明本次提交所作的改动。 这时我们可以再次执行log指令,可以看到提交历史多了一条我们刚才提交的记录: 我们这时再向text.txt添加一段文本,然后再次使用git status指令: 上面这段文本表达的信息: 1.当前在main分支 2.你的分支比远程的origin/main领先一个commit 3.text.txt被修改了,但修改还没有被暂存。使用git add 把工作区中的修改更新到暂存区;使用git restore 放弃工作区中的修改。 Git的提示已经很清楚了,我们只需要再次使用git add和git commit,就完成了第二次提交。再次使用git log查看提交历史: 我们可以看到最上面的总是最新的提交,这是Git默认的设置。 如果窗口区域不足以输出全部信息,Git会等待用户的操作: 此时按下Enter,Git会输出下一行;按下Q,会退出Git。 ⑤把提交推送到远程仓库到目前为止,我们已经在本地写了两条提交,我们想把它们推送到远程仓库,只需要使用push命令。在此之前我们先查看一下status git status可以看到,当前分支已经领先远程分支origin/main两个提交了。 origin/main 的中的 origin 是远端仓库的名称,是你在用 clone 指令初始化本地仓库时 Git 自动帮你起的默认名称;main 是 origin 上的分支名称。 而这句话的下面也说明了,你可以使用 git push 来把你的本地提交发布(即推送到远程仓库)。所以很简单,照做吧: git push第一次提交,可能需要使用输入账户密码进行认证: 输入账户密码之后,我们观察命令行,这时候Git就把本地的提交到远程仓库了。 5.本地创建仓库并关联到远程仓库把本地仓库管理到远程仓库,有两种情况:要么本地已有仓库,要么本地还没有仓库。如果本地还没有创建仓库,则从①开始,如果本地已有一个仓库,直接从②开始: ①在项目目录中新建一个仓库只在需要创建仓库的项目目录,使用命令git init即可创建一个新的仓库 git默认的分支名为master 然后在目录中添加一个.gitignore文件,在前面介绍过,它相当于忽略名单,用于设置不允许git跟踪的文件,避免一些不需要的文件被加入仓库。示例如下: 最好再添加一个readme.md或readme.txt文件,用于介绍这个仓库。.md是一种轻量化的格式文件,全称markdown。 使用git add和git commit提交代码到本地仓库。只有产生一次提交之后,才能进行后续的操作 ②创建一个空白的远程仓库这次使用Gitee做演示,访问远程仓库Gitee.com。(Github也可以,不过Github是国外网站,访问速度较慢) 注册或者登录账号 点击仓库列表右边+号,创建一个远程仓库 进入仓库配置页面,只需要设置仓库的名称即可 创建完成之后,我们可以看到仓库是一个完全空白的仓库,里面只有一些Gitee的提示。 上面创建的空白的远程仓库已经提示我们应该怎么操作了,我们照做即可: git remote add origin https://gitee.com/sq800/new-repo.gitorigin是远程仓库的别名,代表后面的链接指向远程仓库,也可以设置为其他字符串。 例如,示例使用的是Gitee,我们也可以把别名设置为gitee git remote add gitee https://gitee.com/sq800/new-repo.git ④把本地提交推送到远程仓库 git push -u origin master这里-u可以不加,加上-u,下次再推送到这个分支,可以简化为git push。 不出意外的话,我们本地的仓库就提交到远程仓库了。 6.HEAD、master、分支的本质我们使用git log看一下commit(提交)历史: 我们以这两个提交举例说明。每一个commit后面的的一长串字符串是它的哈希值,前面4.②中我们已经介绍过了,哈希值是指向这个提交唯一的方式。 后面的(HEAD -> master, main),是两个指向这个commit的引用。下面红色的(gitea/main),是远程仓库gitea(别名)的main分支指向的提交。 这说明当前本地仓库已经领先了远程仓库gitea一个提交。 HEAD:当前commit的引用HEAD是引用中最特殊的一个,它指向当前commit的引用,所谓当前 commit这个概念很简单,它指的就是当前工作目录所对应的 commit。上图中当前的commit就是最新的那个commit,每次当有新的 commit 的时候,HEAD 会转而指向最新的 commit。 事实上,当使用 checkout、reset 等指令手动指定改变当前 commit 的时候,HEAD 也会一起跟过去。 总之,当前 commit 在哪里,HEAD 就在哪里,这是一个永远自动指向当前 commit 的引用,所以你永远可以用 HEAD 来操作当前 commit。 分支(branch)分支也是一个引用,它也指向一个commit HEAD除了可以指向某个提交,也可以指向一个分支,当它指向某个 branch 的时候,会通过这个 branch 来间接地指向某个 commit;另外,当 HEAD 在提交时自动向前移动的时候,它会带着它所指向的 branch 一起移动。 例如上面那张图,HEAD -> master中的master就是一个分支的名字,而它左边的箭头表示HEAD正在指向它,如果这个时候再提交一次,HEAD和master会一块向前移动。我们可以来验证一下: 这里我省略了修改文件、add和commit的步骤。可以看到,经过一次新的提交后,HEAD以及它指向的master分支,都转而指向了新的的提交,而main分支依然指向原来的commit上,gitea/main 分支也依然指向原来的commit上。 master:默认分支上面的这个 master ,其实是一个特殊的 branch:它是 Git 的默认 branch(俗称主 branch / 主分支)。 所谓的「默认 branch」,主要有两个特点: 新创建的仓库是没有任何 commit 的。但在它创建第一个 commit 时,会把 master 指向它,并把 HEAD 指向 master。 当有人使用 git clone 时,除了从远程仓库把 .git 这个仓库目录下载到工作目录中,还会 checkout (签出) master(checkout 的意思就是把某个 commit 作为当前 commit,把 HEAD 移动过去,并把工作目录的文件内容替换成这个 commit 所对应的内容)。注意:一些远程仓库由于某些原因,在上面创建仓库的时候,会把主分支设置为main。 branch 的通俗化理解尽管在 Git 中,branch 只是一个指向 commit 的引用,但它有一个更通俗的理解:你还可以把一个 branch 理解为从初始 commit 到 branch 所指向的 commit 之间的所有 commit 的一个「串」。例如下面这张图: c0是初始提交,main分支指向c4提交,dev分支指向c3提交 7.创建、切换、合并、删除分支 列出所有分支 git branch*号代表当前所在的分支 创建分支在当前分支基础之上创建分支,新分支拥有当前分支的提交历史 git branch [分支名字]创建一个新分支并切换到新分支 git ckeckout -b [分支名字] 切换分支 git switch [分支名字] 或 git checkout [分支名字] 合并分支合并指定分支到当前分支 git merge [分支名]合并分支会产生一个新提交,HEAD会带着当前分支一起指向新的提交。而被合并的分支依然指向原来的提交。 合并冲突可以参考下一节的合并冲突来解决。 删除分支删除本地的分支 git branch -d [分支名字]删除远程仓库的分支 #删除远程仓库gitea的某个分支,注意,默认分支不可删除 git push gitea -d [分支名字] 8.仓库的同步本地的仓库的提交和远程的仓库的提交要保持一致,需要手动同步,包含拉取和推送。 如果仅仅是一个远程仓库和一个本地仓库,并且只在本地仓库做修改并推送到远程仓库,那么并只需要使用push向远程仓库推送就可以了。 推送使用push把本地仓库的提交推送到远程仓库,前面已经介绍过。代码如下: #把本地main分支推送到origin的main分支 git push origin main #把本地main分支推送到origin的dev分支 git push origin main:dev如果有多个同事共同开发一个项目,他们都向一个远程仓库提交代码。也就是说,不止一个本地仓库关联了远程仓库并推送提交; 或者只有一个人开发项目,但是在远程仓库上直接修改并提交了代码(这里仅用文本做示意): 总之,此时远程仓库包含了本地没有的commit,因此直接push本地仓库上去会报错: git push origin main我们需要先使用pull拉取变化。pull会把远程仓库的commit拉取到本地,并与本地的仓库进行合并,它实际包含fetch和merge两条命令。 #拉取origin上的main分支合并到本地的main分支 git pull origin main #拉取origin上的main分支合并到本地的dev分支 git pull origin main:dev使用git log,可以看到,远程仓库的commit已经被合并到本地仓库了,本地仓库已经完成了与远程仓库的同步: 团队开发时,我们一定会遇到一种情况:当同事A向远程仓库push时,同事B已经向远程仓库push了提交。这时同事A再向远程仓库push时,Git会报错误,错误截图就不放了,和上面的push报错是一样的。 这时候我们需要先把远程仓库的提交pull到本地: #gitea是远程仓库别名,如果名字配的是origin,使用origin即可 git pull gitea mainGit会尝试自动合并冲突,如果冲突无法自动合并,Git会把冲突标记出来,留给我们自行合并。在Vscode中合并冲突如下图所示: 可以看到,text.txt文件产生了冲突:同事A添加的文本“同事A第一次提交”与同事B添加的文本冲突了。绿色块是本地的提交,蓝色块是从远程仓库拉下来的提交,他们之间用多个连续的等号隔开。 色块是VScode对Git的图形化支持。如果用记事本打开这个文件,我们可以看到它原本的样子: 我们可以手动地删除不想要的代码,然后删除掉下图中红框框起来的部分,就完成了合并冲突的第一步。 合并冲突的第二步就是提交修改后的第一步的代码: # 首先把修改好的冲突文件添加到暂存区 git add . git commit -m "合并远程冲突:...."这样就完成了冲突的合并,然后就可以push到远程仓库了 git push gitea main这时候我们看远程仓库,已经成功推送上去了: 写完所有的 commit 后,不用考虑远程仓库是否有新的提交,直接 push 就好 如果其他人已经有过提交,则会 push 失败,就用 git pull 拉取远程仓库的提交与把本地仓库的提交进行合并,然后再 push 一次 git pull包含git merge命令,会自动合并提交,如果遇到合并冲突,则需要手动合并。 9.Git的部分常用操作 提交与修改为便于说明,接下来在目录中新建一些文本文件和目录,分别是empty.txt、file.txt、readme.md和用与存放图片的目录img。 git add --添加文件到暂存区文件添加到暂存区后,Git会自动对文件更改进行跟踪。文件每次修改之后,如果需要提交,都要使用git add命令暂存到暂存区 git add empty.txt可使用命令git status查看当前仓库的状态,显示有变更的文件,可以看到empty.txt被添加到了暂存区: 添加多个文件到暂存区: git add file.txt readme.md添加整个img文件夹到暂存区: git add img添加当前目录全部文件到暂存区: git add . git commit --提交暂存区到本地仓库如果一个文件或文件的修改没有使用git add添加到暂存区进行追踪,那么git commit命令不会把它提交到仓库。 提交暂存区到本地仓库,使用-m附带提交说明 git commit -m "提交说明"提交暂存区指定文件到本地仓库 git commit readme.md file2.txt -m "提交说明"对于已添加到暂存区的文件(已跟踪的文件),可以跳过暂存区,直接提交文件在工作区的修改 git commit -a -m "提交说明" git status --查看当前仓库的状态查看上次提交之后是否对文件有修改。 常见的状态有: 状态 说明 Changes to be committed 暂存区暂存的修改,等待被提交 Changes not staged for commit 文件在工作区已被修改,等待暂存 Untracked files 未添加到暂存区的文件 git diff --比较文件差异比较文件在暂存区和工作区的差异: git diff file2.txt比较暂存区和上一次提交的差异 git diff --cached file2.txt 或 git diff --staged file2.txt比较两次提交的差异,需要使用两次提交的哈希值,哈希值可以通过git log获取。 git diff [hash1] [hash2]可以使用代码编辑器例如VScode来对比文件差异,可以清楚地查看文件的不同之处 git rm --从暂存区删除文件从暂存区删除文件1.txt,不再跟踪它的变化,把它保留在工作区 git rm --cached 1.txt从暂存区和工作区中删除文件1.txt git rm 1.txt git restore --恢复操作放弃在工作区对a.txt的修改,把暂存区的版本恢复到工作区 git restore a.txt 或 git checkout -- a.txt放弃添加到暂存区的修改,恢复暂存区到添加前的状态,工作区不变: git restore --staged a.txt 或 git reset HEAD 查看提交历史与回退版本 git log --查看提交历史默认查看当前分支的历史;加--all 查看全部分支的历史 查看完整提交历史 git log提交记录的哈希值也叫提交ID。 查看最近两次的提交 git log -2查看简短版的提交历史,哈希值被缩短了。为了方便,一般都使用简短的哈希值,它具有唯一性。 git log --oneline查看当前分支的可视化的提交历史: git log --oneline --graph查看全部分支的可视化的提交历史。可以清楚地看到什么时候出现了分支、合并: git log --oneline --graph --all包括提交的哈希、作者名、提交日期 #git blame [文件地址] 例如: git blame readme.md git reset --回退版本重置命令git reset是Git最常用的命令之一,也是最危险,最容易误用的命令。 使用git reset命令,需要使用提交记录的哈希值,可以使用git log --oneline 命令获取某次提交(版本)的哈希值(提交ID)。哈希值是提交记录的绝对引用;如果知道要回退的版本与现在版本的距离,可以使用相对引用HEAD。HEAD可以被理解为“当前分支”,它默认指向当前所在分支的最新的提交,我们的工作都是在HEAD指向的位置上进行的,可以使用cat .git/HEAD查看当前HEAD的指向。HEAD^代表上一次提交,HEAD^^代表前上上一次提交,如果要向前N个版本,也可以使用HEAD~N来简写。 git reset命令的用法: 带文件路径的用法:把暂存区的文件替换为指定commit的版本。下面的命令是用最近一次提交的1.txt替换当前暂存区的1.txt,相当于取消git add 1.txt的操作 git reset HEAD 1.txt不带文件路径的用法: git reset [--soft | --mixed | --hard] [HEAD]/[哈希值]根据soft,mixed,hard的不同,git reset对HEAD(当前分支)、暂存区、工作区也有不同的影响: git reset --hard 9d60796当前分支回滚到哈希值9d60796指向的版本;暂存区被替换为9d60796的版本内容;工作区被替换为9d60796的版本内容。(工作区与暂存区未提交的代码会丢失) git reset --soft 9d60796当前分支回滚到9d60796的版本;不改变暂存区与工作区。 git reset --mixed 9d60796当前分支回滚到9d60796的版本;暂存区被替换为9d60796的版本内容;不改变工作区。可以省略--mixed,不使用参数,默认为--mixed。 |
CopyRight 2018-2019 实验室设备网 版权所有 |