Git是目前世界上最先进的分布式版本控制系统,没有之一,对,没有之一。著名的同性交友网站-Github,使用的就是Git存储。无数的开源项目在Github上汇聚,由此可知Git的威力。
Git是一个分布式的版本控制系统,与集中式的版本控制系统不同的是,每个人都工作在通过克隆建立的本地版本库中。也就是说每个人都拥有一个完整的版本库,查看提交日志、提交、创建里程碑和分支、合并分支、回退等所有操作都直接在本地完成而不需要网络连接。
对于Git仓库来说,每个人都有一个独立完整的仓库,所谓的远程仓库或是服务器仓库其实也是一个仓库,只不过这台主机24小时运行,它是一个稳定的仓库,供他人克隆、推送,也从服务器仓库中拉取别人的提交。
Git是Linux之父Linus的第二个伟大的作品,它最早是在Linux上开发的,被用来管理Linux核心的源代码。后来慢慢地有人将其移植到了Unix、Windows、Max OS等操作系统中。
想要使用Git,第一步当然是安装。
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install git
linux系统
yum -y install git
windows:
先从官网下载最新版本的Git
官网地址:https://git-scm.com/downloads
git config --global user.name "chenshifeng" git config --global user.email "1162704960@qq.com"
ssh-keygen -t rsa -C "1162704960@qq.com"
git config --list 或者 git config -l 可查看git的配置信息
chenshifengdeMacBook-Pro:PythonCode chenshifeng$ git config -l credential.helper=osxkeychain user.name=chenshifeng user.email=1162704960@qq.com core.autocrlf=input
创建版本库非常的简单,选择一个合适的地方,使用下面的命令创建版本库。
chenshifengdeMacBook-Pro:PythonCode chenshifeng$ mkdir gitstudy # 创建文件夹 chenshifengdeMacBook-Pro:PythonCode chenshifeng$ cd gitstudy # 进入文件夹 chenshifengdeMacBook-Pro:PythonCode chenshifeng$ git init # 初始化成Git版本库 Reinitialized existing Git repository in /Users/chenshifeng/MyCode/PythonCode/gitstudy/.git/至此一个空的Git仓库就创建好了,就是这么的简单。在这个目录下你会看到一个
.git
目录。这个目录就是Git用来跟踪管理版本库的。所以千万不要修改删除这个文件夹中的文件。因为这是隐藏目录,所以如果你看不见可以使用命令ls -a
来查看。
当创建好了一个版本库之后,我们就可以在版本库中进行版本控制了。所以我们需要了解一下Git的一些基本命令。
git add # 将工作区的修改提交到暂存区 git commit -m 'remarks' # 将暂存区的修改提交到当前分支 -m,添加备注 git status # 查看当前仓库的状态 git diff # 查看修改 git log # 查看提交历史 git restore <file> # 回退工作区 git restore --staged <file> # 回退暂存区 git reset # 回退到某一个版本 git reset --hard HEAD^ # 回退到上一个版本 git reflog # 查看历史命令,类似与Linux中的history
上面说到了工作区和暂存区的概念,想要用好Git,那么了解Git中的工作区、暂存区之间的关系是很重要的。先来看一张图。
工作区:在你的电脑中可以看见的Git仓库的那个目录,如之前我创建的TestGit
目录。那文件夹就是一个工作区。当我们往版本库提交的时候有两个步骤:
git add # 这一步就是将工作区中修改添加到暂存区(stage)中。 git commit # 这一步其实就是将暂存区中的修改添加到当前的分支中。
所以我们在提交的时候一般都是这样:
$ git add . # 将工作区中所有修改提交到暂存区,"."点的含义就是所有修改 $ git commit -m "first commit" # 将暂存区的所有修改提交到当前分支,-m参数是填写当前提交的备注
1、新建创库上传
chenshifengdeMacBook-Pro:PythonCode chenshifeng$ mkdir testgit chenshifengdeMacBook-Pro:PythonCode chenshifeng$ cd testgit/ chenshifengdeMacBook-Pro:testgit chenshifeng$ git init Initialized empty Git repository in /Users/chenshifeng/MyCode/PythonCode/testgit/.git/ chenshifengdeMacBook-Pro:testgit chenshifeng$ ls -a . .. .git chenshifengdeMacBook-Pro:testgit chenshifeng$ vi readme.txt chenshifengdeMacBook-Pro:testgit chenshifeng$ git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) readme.txt nothing added to commit but untracked files present (use "git add" to track) chenshifengdeMacBook-Pro:testgit chenshifeng$ git add ./readme.txt chenshifengdeMacBook-Pro:testgit chenshifeng$ git commit -m 'add firstday' [master (root-commit) f150f5d] add firstday file changed, 1 insertion(+) create mode 100644 readme.txt chenshifengdeMacBook-Pro:testgit chenshifeng$
2、修改并提交
chenshifengdeMacBook-Pro:testgit chenshifeng$ vi readme.txt chenshifengdeMacBook-Pro:testgit chenshifeng$ git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: readme.txt no changes added to commit (use "git add" and/or "git commit -a") chenshifengdeMacBook-Pro:testgit chenshifeng$ git add ./readme.txt chenshifengdeMacBook-Pro:testgit chenshifeng$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: readme.txt chenshifengdeMacBook-Pro:testgit chenshifeng$ git commit -m 'add second day' [master 5cf7dbe] add second day file changed, 1 insertion(+) chenshifengdeMacBook-Pro:testgit chenshifeng$ git status On branch master nothing to commit, working tree clean chenshifengdeMacBook-Pro:testgit chenshifeng$ git diff chenshifengdeMacBook-Pro:testgit chenshifeng$
3、修改并查看不同
chenshifengdeMacBook-Pro:testgit chenshifeng$ vi readme.txt chenshifengdeMacBook-Pro:testgit chenshifeng$ git diff # 与暂存区相比,删除second day,增加123456 diff --git a/readme.txt b/readme.txt index 3a25b02..b65492c 100644 --- a/readme.txt +++ b/readme.txt @@ -1,2 +1,2 @@ firday -second day +12345
撤销/回退三板斧
回退工作区、回退临时区、回退版本
git check out
git reset HEAD <file>
回退工作区
chenshifengdeMacBook-Pro:testgit chenshifeng$ cat readme.txt firday second day chenshifengdeMacBook-Pro:testgit chenshifeng$ git status On branch master nothing to commit, working tree clean chenshifengdeMacBook-Pro:testgit chenshifeng$ vi readme.txt chenshifengdeMacBook-Pro:testgit chenshifeng$ cat readme.txt firday second day i am stupid chenshifengdeMacBook-Pro:testgit chenshifeng$ git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: readme.txt no changes added to commit (use "git add" and/or "git commit -a") chenshifengdeMacBook-Pro:testgit chenshifeng$ git restore ./readme.txt chenshifengdeMacBook-Pro:testgit chenshifeng$ cat readme.txt firday second day chenshifengdeMacBook-Pro:testgit chenshifeng$
其中,git restore也可以使用git checkout来完成
chenshifengdeMacBook-Pro:testgit chenshifeng$ cat readme.txt firday second day i am stupid chenshifengdeMacBook-Pro:testgit chenshifeng$ git checkout -- ./readme.txt chenshifengdeMacBook-Pro:testgit chenshifeng$ cat readme.txt firday second day chenshifengdeMacBook-Pro:testgit chenshifeng$
回退临时区,需先回退临时区,再回退工作区
chenshifengdeMacBook-Pro:testgit chenshifeng$ cat readme.txt firday second day i am stupid chenshifengdeMacBook-Pro:testgit chenshifeng$ git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: readme.txt no changes added to commit (use "git add" and/or "git commit -a") chenshifengdeMacBook-Pro:testgit chenshifeng$ git add ./readme.txt chenshifengdeMacBook-Pro:testgit chenshifeng$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: readme.txt chenshifengdeMacBook-Pro:testgit chenshifeng$ git restore --staged ./readme.txt #回退临时区 也可以用 git reset HEAD ./readme.txt chenshifengdeMacBook-Pro:testgit chenshifeng$ git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) #回退工作区 modified: readme.txt no changes added to commit (use "git add" and/or "git commit -a") chenshifengdeMacBook-Pro:testgit chenshifeng$ git restore ./readme.txt # 或 git checkout -- ./readme.txt chenshifengdeMacBook-Pro:testgit chenshifeng$ git status On branch master nothing to commit, working tree clean chenshifengdeMacBook-Pro:testgit chenshifeng$ cat readme.txt firday second day chenshifengdeMacBook-Pro:testgit chenshifeng$
回退版本
chenshifengdeMacBook-Pro:testgit chenshifeng$ git log commit af34ca18dab606aa94a688b02d396ba0b82b7f8c (HEAD -> master) Author: chenshifeng <1162704960@qq.com> Date: Mon Oct 19 22:37:13 2020 +0800 add i am stupid commit 5cf7dbe11d8de0c62eaf7e147fb04052242bd1a9 Author: chenshifeng <1162704960@qq.com> Date: Mon Oct 19 21:40:29 2020 +0800 add second day commit f150f5d8213ff09f6513b74e305a4f78c6f2eaf4 Author: chenshifeng <1162704960@qq.com> Date: Mon Oct 19 21:35:00 2020 +0800 add firstday chenshifengdeMacBook-Pro:testgit chenshifeng$ git reset --hard HEAD^ #回退到上一个版本 HEAD is now at 5cf7dbe add second day chenshifengdeMacBook-Pro:testgit chenshifeng$ git log commit 5cf7dbe11d8de0c62eaf7e147fb04052242bd1a9 (HEAD -> master) Author: chenshifeng <1162704960@qq.com> Date: Mon Oct 19 21:40:29 2020 +0800 add second day commit f150f5d8213ff09f6513b74e305a4f78c6f2eaf4 Author: chenshifeng <1162704960@qq.com> Date: Mon Oct 19 21:35:00 2020 +0800 add firstday</span></pre>
该方法会直接把临时区和工作区内容直接回退
chenshifengdeMacBook-Pro:testgit chenshifeng$ git status On branch master nothing to commit, working tree clean chenshifengdeMacBook-Pro:testgit chenshifeng$ cat readme.txt firday second day
上面提到了在 Git
这个版本控制工具下文件的各种状态,其实回退操作就是通过命令实现这些文件状态的“倒退”,进而达到回退操作的目的,下面一起先来了解下这些可以实现回退的命令。
这个命令又出现了,上次是总结 git branch
分支操作的时候,git checkout
可以用来新建或者切换分支,这次总结回退版本的命令,git checkout
也可以用来回退文件版本,很神奇吧。
其实这个命令的作用就是它单词的本义——检出,他的常用操作也取自这个意思,比如 git checkout branch_name
切换分支操作,实际上就是把指定分支在仓库中对应的所有文件检出来覆盖当前工作区,最终表现就是切换了分支。
而针对于文件的检出可以使用 git checkout -- file_name
,当不指定 commit id
就是将暂存区的内容恢复到工作区,也就可以达到回退本地修改的作用。
不过,这个身兼数职的 git checkout
命令现在可以轻松一些了,从 Git 2.23
版本开始引入了两个新的命令: git switch
用来切换分支,git restore
用来还原工作区的文件,这个后面还会提到。
revert 这个词的意思是:归还,复原,回退,它和后面即将提到的 restore 在意思上简直无法区分,为了区别他们两个这里可以把 git revert
看成归还的意思,对某次提交执行 git revert
命令就是对这次修改执行一个归还操作,其实就是反向再修改一次。
要理解 git revert
就要从反向修改的含义来看,当我们再一个文件中添加一行内容,并提交到版本库后,产生一个提交id——commit-id-a
,如果这时使用 git revert commit-id-a
命令,就相当于在工作区中的那个文件将刚在新加的一行内容删除掉,然后再进行一个提交。
注意,这个操作是会改变分支记录的,因为产生了新的提交。
这个命令是 Git 2.23
版本之后新加的,用来分担之前 git checkout
命令的功能,作用就是用暂存区或者版本库中的文件覆盖本地文件的修改可以达到回退修改的目的,同时也可以使用版本库中的文件覆盖暂存区的文件,达到回退git add
命令的目的。
注意,这个操作是不会影响分支记录的,就是相当于之前的 git checkout
命令重新检出一份文件来覆盖本地的修改。
reset 重新设置的意思,其实就是用来设置分支的头部指向,当进行了一系列的提交之后,忽然发现最近的几次提交有问题,想从提交记录中删除,这是就会用到 git reset
命令,这个命令后面跟 commit id
,表示当前分支回退到这个 commit id
对应的状态,之后的日志记录被删除,工作区中的文件状态根据参数的不同会恢复到不同的状态。
--soft
: 被回退的那些版本的修改会被放在暂存区,可以再次提交。
--mixed
: 默认选项,被回退的那些版本的修改会放在工作目录,可以先加到暂存区,然后再提交。
--hard
: 被回退的那些版本的修改会直接舍弃,好像它们没有来过一样。
这样来看,git set
命令好像是用来回退版本的,但是如果使用 git rest HEAD file_name
命令就可以将一个文件回退到 HEAD
指向版本所对应的状态,其实就是当前版本库中的状态,也就相当于还原了本地的修改。
在使用git commit命令将修改从暂存区提交到本地版本库后,只剩下最后一步将本地版本库的分支推送到远程服务器上对应的分支了
git push的一般形式为 git push <远程主机名> <本地分支名> : <远程分支名> ,例如 git push origin master:refs/for/master ,即是将本地的master分支推送到远程主机origin上的对应master分支, origin 是远程主机名,
第一个master是本地分支名,第二个master是远程分支名。
1.1 git push origin master
如果远程分支被省略,如上则表示将本地分支推送到与之存在追踪关系的远程分支(通常两者同名),如果该远程分支不存在,则会被新建
1.2 git push origin :refs/for/master
如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支,等同于 git push origin --delete master
1.3 git push origin
如果当前分支与远程分支存在追踪关系,则本地分支和远程分支都可以省略,将当前分支推送到origin主机的对应分支
1.4 git push
如果当前分支只有一个远程分支,那么主机名都可以省略,形如 git push,可以使用git branch -r ,查看远程的分支名
1.5 git push 的其他命令
这几个常见的用法已足以满足我们日常开发的使用了,还有几个扩展的用法,如下:
(1) git push -u origin master 如果当前分支与多个主机存在追踪关系,则可以使用 -u 参数指定一个默认主机,这样后面就可以不加任何参数使用git push,
不带任何参数的git push,默认只推送当前分支,这叫做simple方式,还有一种matching方式,会推送所有有对应的远程分支的本地分支, Git 2.0之前默认使用matching,现在改为simple方式
如果想更改设置,可以使用git config命令。git config --global push.default matching OR git config --global push.default simple;可以使用git config -l 查看配置
(2) git push --all origin 当遇到这种情况就是不管是否存在对应的远程分支,将本地的所有分支都推送到远程主机,这时需要 -all 选项
(3) git push --force origin git push的时候需要本地先git pull更新到跟服务器版本一致,如果本地版本库比远程服务器上的低,那么一般会提示你git pull更新,如果一定要提交,那么可以使用这个命令。
(4) git push origin --tags //git push 的时候不会推送分支,如果一定要推送标签的话那么可以使用这个命令
1.6 关于 refs/for
// refs/for 的意义在于我们提交代码到服务器之后是需要经过code review 之后才能进行merge的,而refs/heads 不需要
git branch
$ git branch * br-2.1.2.2 master
$ git branch -r origin/HEAD -> origin/master origin/feature/IOS_visualtrack origin/feature/android_visualtrack origin/master
$ git branch -a * br-2.1.2.2 master remotes/origin/HEAD -> origin/master remotes/origin/br-2.1.2.1 remotes/origin/br-2.1.2.2 remotes/origin/br-2.1.3 remotes/origin/master
PS: git branch -r 无法获取远程分支,ui可以看见分支但是git 命令无法查看
原因 git branch -a 这条命令并没有每一次都从远程更新仓库信息,我们可以手动更新一下
git fetch origin git branch -a
创建密钥
ssh-keygen -t rsa -C "123456@qq.com"
123456@qq.com是你注册github时的邮箱名 输入命令后一路回车就行,完成后就会在当前账号的家目录下生产一个.ssh的隐藏文件
chenshifengdeMacBook-Pro:gitstudy chenshifeng$ ssh-keygen -t rsa -C "1162704960@qq.com" Generating public/private rsa key pair. Enter file in which to save the key (/Users/chenshifeng/.ssh/id_rsa): /Users/chenshifeng/.ssh/id_rsa already exists. Overwrite (y/n)?
由于这里我原来已经创建过,这里我选n,没有创建过的,会要求确认路径和输入密码,我们这使用默认的一路回车就行。成功的话会在~/下生成.ssh文件夹,进去,打开id_rsa.pub,复制里面的key。(全选复制即可)
chenshifengdeMacBook-Pro:~ chenshifeng$ ls -a |grep .ssh .ssh chenshifengdeMacBook-Pro:~ chenshifeng$ cd .ssh chenshifengdeMacBook-Pro:.ssh chenshifeng$ ls id_rsa id_rsa.pub known_hosts
登录GitHub(默认你已经注册了GitHub账号),添加ssh key,点击Settings,如图
点击New SSH key,如图添加key,如图
4、链接验证
chenshifengdeMacBook-Pro:~ chenshifeng$ ssh -T git@github.com Hi shifengboy! You've successfully authenticated, but GitHub does not provide shell access.
说明已经链接成功。
创建一个远程创库
将初始引导文案复制出来,有助于使用
echo "# testgit" >> README.md git init git add README.md git commit -m "first commit" git branch -M main git remote add origin https://github.com/shifengboy/testgit.git git push -u origin main
git remote add origin https://github.com/shifengboy/testgit.git git branch -M main git push -u origin main
将本地创库上传到github
chenshifengdeMacBook-Pro:testgit chenshifeng$ git remote add origin https://github.com/shifengboy/testgit.git chenshifengdeMacBook-Pro:testgit chenshifeng$ git branch -M main #可省略 chenshifengdeMacBook-Pro:testgit chenshifeng$ git push -u origin main Enumerating objects: 6, done. Counting objects: 100% (6/6), done. Delta compression using up to 8 threads Compressing objects: 100% (2/2), done. Writing objects: 100% (6/6), 445 bytes | 445.00 KiB/s, done. Total 6 (delta 0), reused 0 (delta 0) To https://github.com/shifengboy/testgit.git * [new branch] main -> main Branch 'main' set up to track remote branch 'main' from 'origin'. chenshifengdeMacBook-Pro:testgit chenshifeng$
如图,代码已上传成功
如果说git创库是游戏本地存档,那么github就是游戏网络存档