资料
首先推荐几个系统学习git的资料网站
git和GitHub的区别
- git是什么
Git 是一个免费并且开源的分布式版本控制系统,旨在快速高效地处理从小到大所有项目的版本管理。
Git 非常容易学习,低植入,高性能。因为拥有轻量的本地分支,易用的暂存区,和多工作流的特点,它超越了类似Subversion, CVS,Perforce和ClearCase的其他的 SCM 工具。
简洁来说,Git是一个分布式版本控制系统。
换句话说,git就是一个文本历史版本管理工具。它可以管理文件的修改,并记录下来每次操作的修改部分。在Git管理下,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
- GitHub是什么
GitHub,地址:How people build software · GitHub ,主要提供基于git的版本托管服务。一经上线,它的发展速度惊为天人,截止目前,GitHub 已经发展成全球最大的开源社区。
GitHub 上的代码仓库,只支持 Git 做版本管理,只有通过 Git 才能把代码上传到 GitHub 。
以上就是 Git 和 GitHub 的关系。
git安装与配置
- Mac下git的安装与配置(仅列出Mac安装指南)
通用术语
术语
- 版本库(repository)也叫仓库(也可以看作目录,目录下的所有文件由git管理,git对文件进行追踪)
- 工作目录/工作区(working space)持有实际文件,就是你电脑里能看到的目录,比如我的文件夹
- 暂存区(stage或index)它像个缓存区域,临时保存你的更改,
- HEAD,它指向你最后一次提交的结果。可以理解为HEAD就是git版本库。我们创建git版本库时,Git自动为我们创建了唯一一个master分支,这里在master分支上,HEAD指向master,master即指最近的一次提交
- origin(远程仓库):origin是默认命名,即你所关联的远程库。
提交项目
先有本地库,再有远程库
- 创建新仓库
创建新文件夹,打开,然后执行git init
以创建新的 git 仓库。
通过git init
这个目录变成Git可以管理的仓库
$git init
Initialized empty Git repository in /Users/XXX/Desktop/Test1/.git/
这样Git就把仓库建好啦,我们可以看到在当前目录下多了一个 .git 的目录,这个目录是Git来跟踪管理版本库的。
- 把文件添加到版本库
我们在test1目录下,编写一个文件
$touch testing
$vim testing
//内容如下
wewfhsaivb
(1)用git add
命令将文件提交到暂存区
$git add testing
执行以上命令,没有任何显示。
(2)用 git commit
命令,提交更改,实际上就是把暂存区的所有内容提交到当前分支(我们创建git版本库时,Git自动为我们创建了唯一一个master分支,这里在master分支上,HEAD指向master,master即指最近的一次提交):
$ git commit -m "编写testing"
[master (root-commit) 51a883d] 编写testing
1 file changed, 1 insertion(+)
create mode 100644 testing
提交工作流如下图所示
git结构(工作区,暂存区,版本库)
- 工作区(Working Directory):Test1文件夹就是一个工作区
- 版本库(Repository)
工作区有个隐藏目录 .git ,这个不算工作区,而是 Git 的版本库。即上文使用git init
命令创建的git版本库
版本库里面的 index(stage) 文件叫暂存区,还有Git为我们自动创建的第一个分支 master ,以及指向 master 的一个指针叫做 HEAD。
如上文,如果我们想把文件添加到Git版本库里面时,需要分两步:
第一步是用git add
把文件添加进去,实际上就是把文件修改添加到暂存区。
第二步是用git commit
提交更改,实际上就是把暂存区的所有内容提交到当前分支。(我们现在只有唯一一个分支 master,所以现在就是往 master 分支上提交更改)
口说无凭,让我们来练习一下吧
我们在testing文件中再加一点东西
wewfhsaivb
fffgdsaa
顺便再建立一个testing222的文件
然后,让我们使用git status
命令来查看一下各个文件的状态
$ 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: testing
Untracked files:
(use "git add <file>..." to include in what will be committed)
testing222
no changes added to commit (use "git add" and/or "git commit -a")
两个文件,两种状态
(1)Untracked files: 有未追踪文件testing222,即testing222还没有提交到暂存区,快使用git add
命令提交testing222到暂存区
(2)changes not staged for commit:有已经提交到暂存区的文件(即已追踪文件)testing 做了修改(modified: testing),修改后还没提交到暂存区,同样使用git add
命令来暂存这次修改
可以这么说第二次修改并没有被提交。因为在工作区的第一次修改被放入暂存区,准备提交;而在工作区的第二次修改并没有被放入暂存区,所以git跟踪并管理的不是文件,而是修改
现在的状态
使用git add
添加之后,使用git status
来查看一下
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: testing
new file: testing222
现在暂存区状态即为这样的
用 git commit
命令把暂存区的所有修改提交到分支
git commit -m "Test222" //引号里面可以写提交的注释
[main 44c0b7f] Test222
2 files changed, 4 insertions(+), 1 deletion(-)
create mode 100644 testing222
再用git status命令查看一下当前状态
$ git status
On branch master
nothing to commit, working tree clean
现在,暂存区的状态就变成这样了:
总结:
当你运行git status
这个命令时,通常文件会有这么几种状态
- Untracked (未跟踪文件)也就是说你在本地新建新写的文件,意味着 Git 在之前的快照(提交)中没有这些文件,(通俗的说就是这些文件你都没有add过,使用命令 git add 开始跟踪一个文件。)
- Changes to be committed: 意思是该文件已被追踪,并处于暂存状态,即已暂存文件
- Changes not staged for commit:意思是说明已跟踪文件的内容发生了变化,但还没有放到暂存区。 要暂存这次更新,需要运行 git add 命令
- Your branch is up-to-date :通过运行
git commit
创建了第一个提交,此时你的文件已经提交到了版本库上的master分支上。
讲解本地工作区和暂存区的强烈推荐git官方文档,虽然很长,但是讲解很细。链接在下面
git-记录每次更新到仓库
建议过完此过程后,再看一下这两篇博客用于对比和巩固。
工作区和暂存区
参考博客git教程
一张比较完整的git结构图,关于stash的内容之后再说。
添加远程仓库
如果你还没有注册GitHub账号,或者还没有做一些准备工作请参考这篇文章的前两步
- 我们从添加一个远程的仓库开始:
现在的情景是,你已经在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作,真是一举多得。
首先,登陆GitHub,在右上角找到“Create a new repo”按钮,创建一个新的仓库
(用了一个别人的图,关系不大)在Repository name填入 learngit (因为创建完成了,所以提示此用户名存在)其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库:
创建好仓库之后,我们可以把本地仓库和远程仓库进行关联起来了
输入命令
git remote add origin https://github.com/egggg369/xwlces.git //http地址在下图展示出来,可以直接复制
这张图片是已经关联成功的,可以看到本地文件已经传到了远程仓库上,http地址在clone按钮那里,可以直接复制。
关联成功后,即可推送。输入命令git push
,实际上是把当前分支master推送到远程。
git push -u origin master
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
这样就推送成功了。
然而然而!!!! 因为git远程仓库默认分支名字从master变成了main(出于尊重黑人的一些原因。。。。master改main),所以现在如果按照之前的一些教程再输这个命令,就会发现git远程仓库上有两个分支了。。。小白注意哦!!
如果你想让你的远程仓库只有一个分支,应该怎么做呢?
- 不如直接把本地分支也修改为main
git checkout -b main 新建main分支,并转至main分支
git merge master 合并两个分支
然后就可以进行add,commit
git push -u origin main ,将本地main分支的推送至远程
- 千万千万不要直接
git it push -u origin main
//会出现此种错误
error: src refspec main does not match any
error: failed to push some refs to 'https://github.com/egggg369/xwlces.git'
意思是说,远程没有对应的分支,因为你当前本地的分支是master,而远程仓库分支叫main,两者无法关联直接推送
- 先上传至master分支,也就是说现在远程仓库上有两个分支,然后手动合并两个分支,然后再删除master分支。
$ git push origin master
Enumerating objects: 24, done.
Merge branch 'master' of https://github.com/egggg369/xwlces into main
Counting objects: 100% (24/24), done.
Delta compression using up to 4 threads
Compressing objects: 100% (16/16), done.
Writing objects: 100% (24/24), 15.60 KiB | 3.12 MiB/s, done.
Total 24 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), done.
remote:
remote: Create a pull request for 'master' on GitHub by visiting:
remote: https://github.com/egggg369/xwlces/pull/new/master
remote:
To https://github.com/egggg369/xwlces.git
* [new branch] master -> master
$ git checkout main
Branch 'main' set up to track remote branch 'main' from 'origin'.
Switched to a new branch 'main'
$ git pull origin master --allow-unrelated-histories
//此处省略一些字
$ git push origin main//成功!!
- 你也可以快速设置 Git 默认分支由 master 变为 main,把本地的改成main
具体参考这篇博客这里不做赘述了 - 总之总之就是都很麻烦,不改的话很不完美,所以为何不用另外一种方法呢!!!!
不如我们先有远程库,再提交本地库吧!!!
从远程库克隆
先有远程库,从远程库克隆,再提交本地文件
我们重新建立一个远程库和一个待提交本地文件来做示例
-
登陆GitHub,建立一个新仓库叫Test333,建立方法和上文基本一致,勾选
Initialize this repository with a README
,这样GitHub会自动为我们创建一个README.md文件。创建完毕后,可以看到README.md文件:
-
创建完成后,就可以克隆一个本地库了
先进入你的桌面,然后使用git clone
命令
此时你会发现你的桌面上出现了新克隆下来的文件夹Test333。
$ cd /Users/guohongle/Desktop
guohongle@guohongledeAir ~/Desktop master git clone https://github.com/egggg369/Test333.git
$ Cloning into 'Test333'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
-
如果你想把本地的一些文件推送上去,那么你可以直接把它拖拽到克隆下来的文件夹里(本例中有一个Test444文件夹)
或者你是从零开始还没有写,那么直接在Test333下写文件,也可以创建项目把项目的保存路径设置为为Test333
总而言之就是把你想要提交的项目文件保存到Test333 的路径下。 -
接下来要上传了,过程上文已经详细的讲过,这里不再赘述了,还是最常见的三个命令
git add
git commit
git push
$ git add .
guohongle@guohongledeAir ~/Desktop/Test333 main ✚ git $ commit -m "Test333"
[main 9e8fd9c] Test333
1 file changed, 2 insertions(+)
create mode 100644 Test444/Testing444
$ git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 334 bytes | 334.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To https://github.com/egggg369/Test333.git
134d143..9e8fd9c main -> main
- 查看GitHub上的远程仓库,发现你的文件已经上传上去啦!
总结:
上面一种情况是先有了本地库,后有远程库,然后再对远程库进行关联
底下情况是先创建远程库,再从远程库克隆
一般建议呢,使用第二种方法更佳。
上传文件到远程仓库的方式有很多,请灵活应变,记住三个重要命令,以不变应万变!
本篇内容就到这里了,主要是git上传代码的一些注意事项,其他一些命令(回退,查看修改,撤销,删除等)就不做介绍了,如果对合作开发,分支管理感兴趣,请看我下篇博客。