当前位置:   article > 正文

Git的安装配置与项目管理_no changes added to commit (use "git add" and/or "

no changes added to commit (use "git add" and/or "git commit -a")

Git安装

下载安装即可,安装后配置账户名和密码:

$ git config --global user.name  "you name"
$ git config --global user.email "your email"
  • 1
  • 2

:配置完成后,可在用户目录(例如:C:\Users\Maste)下看到.gitconfig文件,里面就是刚才的配置内容。

设置git的版本库/本地仓库(Repository)

先定位到想要作为本地仓库的目录(例如, /e/softWork/git_repository),然后执行: git init

MasterQKK@LENOVOQKK MINGW64 /e/softWork/git_repository
$ git init
Initialized empty Git repository in E:/softWork/git_repository/.git/
  • 1
  • 2
  • 3

文件系统定位到相应目录,可以看到多了一个隐藏文件夹.git
在这里插入图片描述
注:不要修改./git/下的内容。

配置Git与Github远程仓库之间的通讯

由于Git本地仓库和github远程仓库之间的传输是通过SSH加密的,因此需要做配置。
配置步骤:
Step 1: 生成SSH key

$ ssh-keygen -t rsa -C "you email"
  • 1

回车,然后按提示输入:

Enter file in which to save the key (/c/Users/Maste/.ssh/id_rsa):
//输入保存密约的文件名,直接回车,默认名称为:id_rsa Enter passphrase (empty for no
passphrase): // 设置SSH传输时所需的密码,可不设

生成后, 可在C:\Users\Maste.ssh下看到两个文件: (1)id_rsa:存放私约; (2)id_rsa.pub:存放公约。
: 如果出现没有.ssh目录的情形,可再输入命令:ssh-keygen -o,两个回车,即可。
Step 2: github设置SSH
Github->settings->SSH and GPG keys->New SSH Key->然后输入title,再把id_rsa.pub中的内容拷贝至“key”中->Add SSH key,即可。完成效果如图。
在这里插入图片描述

重要概念的介绍

下面这张图概括了几乎所有的操作
在这里插入图片描述
Remote: 远程仓库

Repository: 本地仓库/版本控制, 即目录:/e/softWork/git_repository/.git

Index/Stage: 暂存区,暂存区是介于Repository和Workspace中间的一个概念,相当于一个缓冲区,

Workspace: 工作区,通俗来说,所有目录都是工作区,包括 /e/softWork/git_repository下面除了.git以外的目录。

操作解析

本地仓库Repository与工作区Workspace的交互

提交文件到Index再到Repository

任意目录下(例如:/e/softWork/git_repository/)创建文件readme.txt, 内容:xxxxxx test xxxxxxxxxxxxxx,

$ git add readme.txt // 将readme.txt添加到暂存区
$ git commit -m 'readme.txt提交' // 将readme.txt从到暂存区提交到Repository,'readme.txt提交'为对本次提交的描述
$ git status  // 查看当前状态
  • 1
  • 2
  • 3

可以看到:

On branch master, nothing to commit, working tree clean

继续修改readme.txt, 添加第二行内容:modify now,然后,

$ git status
  • 1

输出内容:可以看到readme.txt已被修改,但还没有暂存/提交.

On branch master Changes not staged for commit: (use “git add
…” to update what will be committed) (use “git checkout –
…” to discard changes in working directory)

modified: readme.txt

no changes added to commit (use “git add” and/or “git commit -a”)

$ git diff readme.txt // 对比修改前后内容变化
  • 1

diff --git a/readme.txt b/readme.txt index c707df6…3dc74f6 100644
— a/readme.txt
+++ b/readme.txt @@ -1 +1,2 @@
-xxxxxx test xxxxxxxxxxxxxx \ No newline at end of file
+xxxxxx test xxxxxxxxxxxxxx
+modify now \ No newline at end of file

$ git add readme.txt  // 添加到暂存区
$ git commit -m  '修改了readme.txt的内容'  // 再提交到repository
$ git status //查看状态
  • 1
  • 2
  • 3

On branch master nothing to commit, working tree clean

可以看到没有要提交的文件了。
继续修改readme.txt, 添加第三行内容:**modify second **,然后,

$ git add readme.txt  // 添加到暂存区
$ git commit -m  '再次修改了readme.txt的内容'  // 再提交到repository
  • 1
  • 2

回退到指定历史版本再回退到最新版本

$ git log --pretty=oneline  //  查看历史记录
  • 1

可以看到,共三次操作记录日志(从近到远):

4d242b5c4b04daee31dbd4bf2b6f100d76c71763 (HEAD -> master)再次修改了readme.txt的内容
c6ff4528c1bd0444b9c05dd68f7a814e281dea8a 修改了readme.txt的内容
977c2029a3a84c91478c2dc40901531526a3bc6b readme.txt提交

$ git reset --hard HEAD^  // 回退到最近的上一个版本
  • 1

HEAD is now at c6ff452 修改了readme.txt的内容

$ cat readme.txt // 查看文件内容
  • 1

可以看到文件已经回退到第一次修改后:

xxxxxx test xxxxxxxxxxxxxx
modify now

$ git log // 查看历史记录
  • 1

可以看到 历史记录也同步进行了更新:没有第二次修改记录

c6ff4528c1bd0444b9c05dd68f7a814e281dea8a (HEAD -> master) 修改了readme.txt的内容
977c2029a3a84c91478c2dc40901531526a3bc6b readme.txt提交

如何再回退到第二次修改记录???

$ git reflog  // 获取第二次修改的版本号4d242b5
  • 1

c6ff452 (HEAD -> master) HEAD@{0}: reset: moving to HEAD^
4d242b5 HEAD@{1}: commit: 再次修改了readme.txt的内容
c6ff452 (HEAD -> master) HEAD@{2}: commit: 修改了readme.txt的内容
977c202 HEAD@{3}: commit (initial): readme.txt提交

$ git reset --hard 4d242b5  // 通过版本号回退到第二次修改
$ cat readme.txt  // 查看文件内容
  • 1
  • 2

结果如下:

xxxxxx test xxxxxxxxxxxxxx
modify now
modify second

第三次修改readmetxt, 添加内容:modify third, 同时新建文件test.txt,内容:XXXXXXXX…XXXXXXXXXX,

 git status // 查看状态
  • 1

On branch master Changes not staged for commit: (use “git add
…” to update what will be committed) (use “git checkout –
…” to discard changes in working directory)
modified: readme.txt
Untracked files: (use “git add …” to include in what will be
committed)
test.txt
no changes added to commit (use “git add” and/or “git commit -a”)

$ git add readme.txt // readme.txt存到暂存区
$ git add test.txt  // test.txt 放到暂存区
$ git commit -m "提交两个文件,一个modified,一个new file"  //全部提交到repository
  • 1
  • 2
  • 3

撤销修改

对readme.txt做第四次修改,添加: modify four, 反悔不想修改了怎么办??
解决方法
(1)直接把readme.txt恢复原状,然后 add-commit即可, 这是最笨的方法, 不管readme.txt有没有添加到Index这种方法都有效;
(2)通过命令回退到当前版本号(860f5c1), : $ git reset --hard 860f5c1 ,不管eadme.txt有没有添加到Index这种方法都有效;
: 不能通过命令git reset --hard HEAD^, 因为当前修改没有提交,这样做的话会回退到上一次的版本号(4d242b5)。
(3)通过命令 git checkout -- readme.txt, 这时候要分两种情形
情形1:修改后的readme.txt已添加到Index, 这时候执行上述命令不会有任何变化,因为会回到添加暂存区后的状态
情形2:修改后的readme.txt没有添加到Index,这时候执行上述命令会回到当前版本号。

删除文件

首先创建third_file.txt, 然后 add-commit,接着,

$ rm test.txt  // Workspace中删除test.txt
$ rm third_file.txt  // Workspace中删除third_file.txt
$ git status 
  • 1
  • 2
  • 3

可以看到这两个个文件已经从workspace删除

On branch master Changes not staged for commit: (use “git add/rm
…” to update what will be committed) (use “git checkout –
…” to discard changes in working directory)
> deleted: test.txt
deleted: third_file.txt

no changes added to commit (use
“git add” and/or “git commit -a”)

再恢复文件:

$ git checkout -- third_file.txt // 从Repository恢复 third_file.txt
$ git checkout -- test.txt // 从Repository恢复 test.txt
  • 1
  • 2

那么如何从Repository中删除文件呢?

$ git rm third_file.txt  // 从workspace删除third_file.txt,并将该操作传递到Index
$ git commit -m '删除third_file.txt'// 从Repository删除third_file.txt
$ git status
  • 1
  • 2
  • 3

可以用下列命令验证,git checkout -- third_file.txt,结果显示 error: pathspec 'third_file.txt' did not match any file(s) known to git,表明该文件已从repository删除。

github远程仓库与本地仓库repository交互

在github上创建远程仓库

Github->New repository->输入Repository name-> Create repository
创建成功后,仓库名称为git_repository, 如下:
可以看到有好多提示命令,方便项目维护。
在这里插入图片描述

将本地仓库内容推送到远程仓库

现在,远程仓库git_repository(上一步刚创建的)是空的,本地仓库中有两个文件:readme.txt以及test.txt.

$ git remote add origin https://github.com/v3551G/git_repository.git // 其中v3551G是我自己的账户名(账户名的第一个字母会被小写)
$ git branch -M main // 本地仓库分支(默认为master)更改为main
$ git push -u origin main  // 将本地仓库分支main的内容推送到远程仓库,远程库的默认名称为origin
  • 1
  • 2
  • 3

注:
1.git push中的参数-u: 第一次推送时,加上了 –u参数,Git不但会把本地的main分支内容推送的远程新的main分支,还会把本地的main分支和远程的main分支关联起来,在以后的推送或者拉取时就可以简化命令.
2. push时的认证问题
会弹出github的登陆窗口,输入账号密码,会出现错误:Logon failed, use ctrl+c to cancel basic credential prompt. (关于该错误请参考: 链接). 紧接着提示:Username for 'https://github.com': 输入github账号后,又弹出一个密码输入框,再输入密码,这次成功了,输出信息如下:

Enumerating objects: 20, done.
Counting objects: 100% (20/20), done.
Delta compression using up to 8 threads Compressing objects: 100% (13/13), done.
Writing objects: 100% (20/20), 1.66 KiB | 340.00 KiB/s,done.
Total 20 (delta 4), reused 0 (delta 0)
remote: Resolving deltas:100% (4/4), done.
To https://github.com/v3551G/git_repository.git
* [new branch] main -> main
Branch ‘main’ set up to track remote branch ‘main’ from ‘origin’.

推送完成后:
可以看到分支main下有两个文件
在这里插入图片描述

将github远程仓库克隆到本地仓库

在github中创建一个远程仓库,仓库名称:git_repository2, 将该远程仓库克隆到本地仓库:

git clone https://github.com/v3551G/git_repository2.git
  • 1

执行后,在本地仓库Repository根目录:E:\softWork\git_repository下面会看到一个新目录:git_repository2,打开如下:
在这里插入图片描述

github远程仓库之间交互

一个常见的是看到别人的github有一个好的项目:project_name,想把它fork到自己的github上面,只需要进入到该项目主页面,然后点击:Fork,完成后,在自己的github上就多了一个repository:project_name

分支管理

创建与分支合并

相关命令:
git branch //查看分支
git branch name //创建 分支(name)
git checkout name // 由当前分支切换到目标分支(name)
git checkout –b name // 创建+切换分支(name)
git merge name //合并分支(name)到当前分支:
git branch –d name //删除分支
示例
git中每次的提交记录串联起来就形成了一条时间线,对应一个分支,如下所示:
(当前分支main的提交记录)
在这里插入图片描述

$ git branch
$ git checkout -b dev  // 创建分支dev并切换到dev
$ git branch
  • 1
  • 2
  • 3

结果如下:有两个分支,main和dev, 带 * 的为当前分支

  • dev
    main
$ cat readme.txt //查看当前readme.txt的内容
  • 1

结果如下:

xxxxxx test xxxxxxxxxxxxxx
modify now
modify second
modify third
modify four

然后往readme.txt添加内容:add row in branch-dev,再添加-提交:

$ git add readme.txt
$ git commit -m 'dev分支上给readme.txt添加内容'
$ git checkout main  // 切换到main分支
$ cat readme.txt 
  • 1
  • 2
  • 3
  • 4

结果如下: (可以看到,修改了dev分支下的readme.txt文件,main分支下内容并没有变化)

xxxxxx test xxxxxxxxxxxxxx
modify now
modify second
modify third
modify four

$ git merge dev  // 将dev分支合并到当前分支
$ cat readme.txt
  • 1
  • 2

可以看到readme.txt文件已更新

xxxxxx test xxxxxxxxxxxxxx
modify now
modify second
modify third
modify four
add row in branch-dev

$ git branch -d dev // 删除dev分支

合并分支时冲突的处理

场景:先创建dev分支,
main主分支下往readme.txt添加内容: a = 1 + 1 ,然后add-commit
dev分支下往readme.txt添加内容b = 1 + 2, 然后add-commit
再合并这两个分支, $ git merge dev
结果如下:

Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.

解决方法

查看文件内容 $ cat readme.txt

xxxxxx test xxxxxxxxxxxxxx
modify now
modify second
modify third
modify four
add row in branch-dev
<<<<<<< HEAD
a = 1+1
=======
b = 1 + 2
>>>>>>> dev

可以看到Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,其中HEAD指向主分支,
根据实际修改readme.txt后再:

$ git add readme.txt
$ git commit -m 'conflict fixed'
$ git branch -d dev
  • 1
  • 2
  • 3

分支合并模式

分支合并默认采用fast forward模式, 可以禁用这种模式,二者的区别是什么?

$ git checkout -b dev // 创建并切换到分支dev
  • 1

然后往readme.txt添加内容: bbbbbbbbbbbbbbbbbb

$ git add readme.txt // 添加
$ git commit -m 'readme.txt添加内容' // 提交
$ git checkout main // 切换到main
$ git merge --no-ff -m "merge with no-ff" dev // 合并dev->main,禁用fast forward
$ git branch -d dev // 删除dev分支
$ git log --graph --pretty=oneline --abbrev-commit // 带图的简介模式显示提交记录
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

如下图所示,当禁用ff时(–no-ff), 删除dev分支后,该分支(266d025)在log中依然会出现(图模式中有分支), 然而在合并出现冲突(d2aebab)那一次之前还有一次成功合并dev记录(28c9440, 采用ff模式,其在图模式中没有出现分支)。

在这里插入图片描述

Bug分支的使用

实际项目开发中,经常碰到这样的情形:假设你正在dev分支下进行某个子模块的开发任务,并且需要很长时间才能完成(因为尚未完成,不能add-commit),然后领导让你紧急处理一个Bug,该Bug在main分支上。这时候你当然希望:保存现场,去处理Bug, 然后再恢复现场。如何实现呢? 主要靠 git stashgit stash apply 两个命令。

场景模拟
$git checkout -b dev // 创建切换到dev
然后在readme.txt下添加内容:“dev开发,尚未add-commit”, 不要add-commit
$ git stash // 隐藏(保存)现场
$ git status //查看状态
结果如下:

On branch dev
nothing to commit, working tree clean

$ git checkout main // 切换到main分支
$ git checkout -b bug-404 // 创建并切换到bug-404分支
  • 1
  • 2

定位bug问题,假设错误在test.rxt文件中,处理(添加:“修复bug-404”)完成后

$ git add test.txt // 添加
$ git commit -m 'fix bug 404 on branch-bug-404' //提交
$ git checkout main // 切换到main
$ git merge --no-ff -m 'merge bug-404 to main' bug-404   // 合并bug-404 -> main
$ git branch -d bug-404 // bug分支的使命完成,删除
$ cat test.txt  // 查看内容
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

可以看到:
XXXXXXXX…XXXXXXXXXX
修复bug-404

$ git checkout dev  // 切换到dev
$ git status // 查看状态
  • 1
  • 2

On branch dev
nothing to commit, working tree clean

$ git stash list // 查看 之前隐藏的工作现场记录(596cd50 )
  • 1

stash@{0}: WIP on dev: 596cd50 merge with no-ff

$ git stash apply  // 恢复现场
  • 1

结果如下:
(可以看到,readme.txt被修改,还未add-commit, 说明现场已恢复)

On branch dev
Changes not staged for commit:
(use “git add …” to update what will be committed)
(use “git checkout –…” to discard changes in working directory)
modified: readme.txt
no changes added to commit (use “git add” and/or “git commit -a”)

$ git stash drop // stash内容并不删除,需要使用命令git stash drop来删除
  • 1

注: git stash pop 等价于 git stash apply + git stash drop,
接着继续之前的开发, 方便吧!

图示上述过程:
在main和dev上分别执行命令:$ git log --graph --pretty=oneline --abbrev-commit
在这里插入图片描述

(总结)分支管理策略

1.main/master: 作为主分支,应该保持稳定,一般用来发布新版本,只有管理员才有权限操作;
2.dev:可以有多个,一般情况下作为实际工作分支,dev分支代码稳定后可以合并到主分支master上来;
3.bug: 在开发中,碰到严重的bug问题,以通过一个临时分支来维护bug修复,修复完成后,合并分支,然后将临时的分支删除掉。因此在推送到远程库之前,bug分支会被合并到main分支,并被删除。

github远程仓库与本地仓库repository的交互+分支管理(重要)

在之前的“github远程仓库与本地仓库repository的交互”一节中淡化了分支管理这块,现在来重新认识。

推送分支

可以看到,当前repository有两个分支:devmain, repository中的readme.txt文件与远程仓库中的readme.txt不同。
在这里插入图片描述
现在将分支main推送到远程仓库:
通过命令:git push origin main // origin为远程库的默认名称(需要登陆github),结果如下,
在这里插入图片描述
本地repository还有一个分支dev,也将其推送到远程仓库:
通过命令:git push origin dev, 如下,可以看到远程库上也有两个分支:maindev, dev是new branch (远程仓库之前没有该分支).
在这里插入图片描述

多人推送分支时的冲突处理

情景模拟:两个人修改了dev分支下的同一个文件,在推送到远程仓库时产生冲突。
准备工作: 为了模拟另外一个人,将远程库git_repository (目前已有两个分支:maindev)克隆到另外一个目录:E:\softWork\git_repository2

$ cd git_repository2
$ git clone https://github.com/v3551G/git_repository.git // 克隆远程库到本地
$ cd git_repository
$ git branch  // 查看分支
  • 1
  • 2
  • 3
  • 4

结果如下: (可以看到只有主分支main被克隆下来)

  • main

需要先在本地创建dev分支并把远程的origindev分支到本地来

$ git checkout -b dev origin/dev // 创建并切换到dev分支,该分支跟踪远程仓库origin的dev分支(关联起来)
  • 1

结果如下:

Switched to a new branch ‘dev’
Branch ‘dev’ set up to track remote branch ‘dev’ from ‘origin’.

准备工作完成。
接下来, /e/softWork/git_repository2/git_repository (dev)下,
在test.txt文件中添加:‘开发人员1修改’,然后add-commit-push:

$ cat test.txt // 确认已修改
$ git add test.txt
$ git commit -m "开发人员1在test.txt上修改"
$ git push origin dev // origin指向推送的目的地
  • 1
  • 2
  • 3
  • 4

接着 /e/softWork/git_repository (dev)下,

$ cat test.txt // 确认已修改
$ git add test.txt
$ git commit -m "开发人员1在test.txt上修改"
$ git push origin dev 
  • 1
  • 2
  • 3
  • 4

结果如下:(产生冲突)

Logon failed, use ctrl+c to cancel basic credential prompt.
Username for ‘https://github.com’: v3551G
To https://github.com/v3551G/git_repository.git
! [rejected] dev -> dev (fetch first)
error: failed to push some refs to ‘https://github.com/v3551G/git_repository.git’
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., ‘git pull …’) before pushing again.
hint: See the ‘Note about fast-forwards’ in ‘git push --help’ for details.

解决方法:提示中已经说了,先把别人的最新提交抓取下来,在本地合并,解决冲突之后再push. 具体操作如下:

$ git branch --set-upstream-to origin/dev dev  // (很重要)首先指定本地dev与远程origin的dev分支之间的连接
$ git pull // 抓取
  • 1
  • 2

结果如下:(可以看到自己(<<与=之间)和别人修改(=与>>之间)的对比)
在这里插入图片描述
根据实际情况修改好后,再add-commit-push:

$ git add test.txt
$ git commit -m '解决开发1和开发2在test.txt中的冲突'
$ git push origin dev
  • 1
  • 2
  • 3

结果如下: (推送成功)
在这里插入图片描述

其他

1.工作中需要在多个项目中切换时怎么办?

在Git的项目管理机制中, 本地仓库Repository是绑定在项目上的,因此,在不引起歧义的前提下,将本地仓库看做一个项目,仓库名称就是项目名称。因此只要确保不同的本地Repository位于不同的目录,例如,项目A: /dir/project_A, 项目B: /dir/project_B,每个项目下都有.git子目录,就相当于是对应项目的“黑匣子”一样。这样一来,只要进入相应的目录,就可对相应repository/项目进行管理。
:不同仓库之间嵌套的话,在add时会出现如下类似问题:
nothing added to commit but untracked files present

2.对Git中origin,master的理解

origin就是一个名字,它是在你clone一个托管在Github上代码库时,git为你默认创建的指向这个远程代码库的标签
分析: 假设用户userx的仓库有个repository,则代码链接为 https://github.com/user2/repositoryclone到本地后,通过命令git remote -v 可以看到:

origin https://github.com/userx/repository.git (fetch)
origin https://github.com/userx/repository.git (push)

origin指向的就是userx的远程代码库。

进一步,userx可以在本地增加一个远程指向useryrepository仓库的标签

git remote add upstream https://github.com/user1/repository.git // 标签名upstream 
  • 1

再通过命令git remote -v 可以看到:

origin https://github.com/userx/repository.git (fetch)
origin https://github.com/userx/repository.git (push)
upstream https://github.com/usery/repository.git (push)
upstream https://github.com/usery/repository.git (push)

upstream就是指向远程useryrepository仓库的标签。

1.通过git init 来创建本地仓库时git_repository,由于仓库还是空的,此时通过命令git remote -v 什么也看不到, 此时用户userz在github创建一个远程仓库git_repository,然后通过命令与远程库建立连接:git remote add origin git@github.com:userz/git_repository.git。这样,git remote -v 可以看到相关信息。
关于本地库与远程库的映射关系介绍可参考:https://blog.csdn.net/weixin_34015336/article/details/86009771

2.可通过命令 git clone -o booyah来修改默认的origin

master是仓库的默认(主)分支。

补充-更一般的case

本地有个项目, 将其代码上传至Github,
1.先在github创建空的Repository,
2.然后进入到项目的root_directory, 执行$ git init来初始化,
3.执行$git branch来查看分支信息, 如果没有的话,需要执行如下命令来产生默认的master分支,
$git add .
‘ g i t c o m m i t − m ′ u p l o a d i n f o ′ ‘ 然再执行 `git commit -m 'upload info'` 然再执行 gitcommitmuploadinfo然再执行git branch应该能看到分支信息,
3’, 也可执行$git branch -M main 来为当前分支改名;
4. 执行如下命令来建立远程连接,并取名为origin,

$ git remote add origin https://github.com/username/projectname.git
  • 1
  1. 上传本地project到github仓库, 将main分支上传到origin指向的远程仓库,
$ git push -u origin main
  • 1

总结

暂时告一段落,未完待续。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/495546
推荐阅读
相关标签
  

闽ICP备14008679号