从事开发工作以来,不管是git还是svn都有过使用,但都是使用图形化工具。对其中的基本知识和原理并不算很清楚,因此打算写下这篇文章来记录我的git学习,同时希望可以帮助到和我一样存在这种问题的朋友。本篇文章主要是以Mac电脑为例。特别感谢廖雪峰的官方网站。
一.创建版本库
1.首先选择一个合适的地方,创建一个空目录
$ mkdir learngit
$ cd learngit
$ pwd
/Users/mr.m/Desktop/learngit
2.通过git init
命令把这个目录变成Git可以管理的仓库
$git init
Initialized empty Git repository in /Users/mr.m/Desktop/learngit/.git/
这时你会发现目录里多了一个.git
的目录,如果没有的话,使用ls -ah
的命令就可以看到。
3.把文件添加到版本库
现在我们打开Xcode创建一个新的工程,并把项目文件夹挪入learngit
目录下。接下来把这个工程文件放入git仓库中
我的项目文件夹名叫做Text
$ git add Text/*
假如想要提交当前的所有文件,执行命令
$ git add .
查看git状态
$ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: Text/Text.xcodeproj/project.pbxproj
new file: Text/Text.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file: Text/Text.xcodeproj/project.xcworkspace/xcuserdata/mr.m.xcuserdatad/UserInterfaceState.xcuserstate
new file: Text/Text.xcodeproj/xcuserdata/mr.m.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
new file: Text/Text.xcodeproj/xcuserdata/mr.m.xcuserdatad/xcschemes/xcschememanagement.plist
new file: Text/Text/AppDelegate.h
new file: Text/Text/AppDelegate.m
new file: Text/Text/Assets.xcassets/AppIcon.appiconset/Contents.json
new file: Text/Text/Base.lproj/LaunchScreen.storyboard
new file: Text/Text/Base.lproj/Main.storyboard
new file: Text/Text/Info.plist
new file: Text/Text/ViewController.h
new file: Text/Text/ViewController.m
new file: Text/Text/main.m
new file: Text/TextTests/Info.plist
new file: Text/TextTests/TextTests.m
new file: Text/TextUITests/Info.plist
new file: Text/TextUITests/TextUITests.m
如果出现这样的情况,那就表示已经把文件添加到了仓库,但是这还是不够的,因为此时文件还在暂存区,我们需要把文件提交到工作区
git commit -m "你的工作日志"
-m 后面的内容为你提交时自己书写的工作日志,方便了解版本更改动态,至此,你的文件就已经在git的管理之下了。
二.版本回退和文件管理
1.版本回退
在实际工作中,我们需要查看历史记录,使用git log
命令查看:
$ git log
commit b695f8cd873da14574edd531f05baedbd05ef649 (HEAD -> master)
Author: mr.m <xx97923145@126.com>
Date: Tue Dec 19 14:05:42 2017 +0800
second
commit 023ed8e732d55c385e3c2ed29ebeac15f00ecd36
Author: mr.m <xx97923145@126.com>
Date: Tue Dec 19 14:04:09 2017 +0800
first
可以看到,我们总共提交过两个版本,如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline
参数:
$ git log --pretty=oneline
b695f8cd873da14574edd531f05baedbd05ef649 (HEAD -> master) second
023ed8e732d55c385e3c2ed29ebeac15f00ecd36 first
需要额外注意的是上面b695f8cd...
这串信息是版本号。
如果我们想要进行版本回退,首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD
表示当前版本,也就是最新的提交b695f8cd...
,上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100
。
$ git reset --hard HEAD^
HEAD is now at 023ed8e first
$ git log
commit 023ed8e732d55c385e3c2ed29ebeac15f00ecd36 (HEAD -> master)
Author: mr.m <xx97923145@126.com>
Date: Tue Dec 19 14:04:09 2017 +0800
first
这样,我们就退回到了上个版本。
但是,假如你发现,你并不想回到这个版本,你又想要去到退回版本之前的版本怎么办呢?
首先找到你之前的版本号
$ git reflog
023ed8e HEAD@{1}: reset: moving to HEAD^
b695f8c (HEAD -> master) HEAD@{2}: commit: second
023ed8e HEAD@{3}: commit (initial): first
因此我们可以看到目前为止我们对Git做过的所有操作,其中b695f8c
是我们之前版本号的前几位,
特别说明:版本号不需要全部输入,只需要前几位,但也不要太短
$ git reset --hard b695f8c
HEAD is now at b695f8c second
$ git reflog
b695f8c (HEAD -> master) HEAD@{0}: reset: moving to b695f8cd873da14574edd531f05baedbd05ef649
023ed8e HEAD@{1}: reset: moving to HEAD^
b695f8c (HEAD -> master) HEAD@{2}: commit: second
023ed8e HEAD@{3}: commit (initial): first
这样,你就会惊奇的发现,又回到了回退之前的版本。
-
HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令
git reset --hard commit_id
。 -
穿梭前,用
git log
可以查看提交历史,以便确定要回退到哪个版本。 -
要重返未来,用
git reflog
查看命令历史,以便确定要回到未来的哪个版本。
掌握了这些你的版本就可以在过去和未来之间来回穿梭。
2.管理修改
我们在之前的教程中,提到了暂存区的概念,那么,暂存区到底是什么呢?其实就是将你修改的内容,先存放起来的位置,然后才能提交到Git仓库中。也就是说,如果不先将内容存放到暂存区,就无法提交到Git仓库。因此假如有如下两种操作,哪一种可以将代码提交成功呢?
方法一:
1.修改代码内容
$git add Text/*
2.再次修改代码内容
$git commit --m "modify"
方法二:
1.修改代码内容
$git add Text/*
2.再次修改代码内容
$git add Text/*
$git commit --m "modify"
答案你想到了吗?
当然是方法二可以完整提交代码。方法一只能提交第一次修改好的代码,因为第二次修改的代码还没有git add
提交到暂存区。
3.撤销修改
撤销修改分为两种情况,一种情况就是你已经把修改内容添加到了暂存区,另一种是你还没有将修改的内容添加到暂存区(假如你已经把修改内容提交了,想撤销的话,那就需要回退版本,请查询上文)。
这时候我们就会用到一个命令git checkout -- 你的文件名
如果已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
如果修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
4.删除文件
在Git中,一般删除文件需要两步操作,一是删除文件夹中相应文件,二是删除Git版本库中的相应文件
1.$ rm test.txt
2.$ git rm test.txt
假如你在文件中删除了test之后,突然发现,你删错了,怎么办呢?不要惊慌,因为版本库中还有,执行下面的命令
$ git checkout -- test.txt
就可以恢复文件啦。
假如你也在版本库中删除了,
那么朋友,那怕是回退版本才可以喽!
三.远程仓库
创建SSH Key
输入下面的命令,如果有文件id_rsa.pub
或 id_dsa.pub
,则直接进入将SSH key添加到GitHub中
,否则进入第二步生成SSH key
。
ls -al ~/.ssh
# Lists the files in your .ssh directory, if they exist
生成新的ssh key
在终端输入
$ssh-keygen -t rsa -C "youremail@example.com"
你需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可,因为这个Key仅仅用于简单的服务,所以也无需设置密码。
完成后会有如下显示
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/你的电脑用户名/.ssh/id_rsa.
Your public key has been saved in /Users/
你的电脑用户名
/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:5V6ZCQNS/3bVdl0GjGgQpWMFLazxTslnKbW2B1mbC+E example@qq.com
如果服务器端需要公钥, 直接把.ssh目录下的
id_rsa.pub
配置即可,
id_rsa
为私钥一定要保密!!!!
将SSH key添加到GitHub中
直接将SSH key从文件拷贝到粘贴板中,如下:
pbcopy < ~/.ssh/id_rsa.pub
# Copies the contents of the id_rsa.pub file to your clipboard

将复制的SSH Key粘贴进Key,Title可以按心情填写
点“Add SSH key”,你就应该看到已经添加的Key
为什么GitHub需要SSH Key呢?因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。
当然,GitHub允许你添加多个Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的Key都添加到GitHub,就可以在每台电脑上往GitHub推送了。
1.添加远程库
首先在GitHub添加一个新的仓库

填写相应的内容,我们把
Respository name
填写为learngit
,创建仓库。目前,在GitHub上的这个新建仓库还是空的,GitHub告诉我们,可以从这个仓库克隆出新的仓库,也可以把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库。现在,我们根据GitHub的提示,在本地的
learngit
仓库下运行命令:
$ git remote add origin git@github.com:HuskyFly/learngit.git
请千万注意,把上面的HuskyFly
替换成你自己的GitHub账户名
添加后,远程库的名字就是origin
,这是Git默认的叫法,也可以改成别的,但是origin
这个名字一看就知道是远程库。
下一步,就可以把本地库的所有内容推送到远程库上:
$ git push -u origin master
Counting objects: 19, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (19/19), done.
Writing objects: 100% (19/19), 13.73 KiB, done.
Total 23 (delta 6), reused 0 (delta 0)
To git@github.com:michaelliao/learngit.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
把本地库的内容推送到远程,用git push
命令,实际上是把当前分支master
推送到远程。
由于远程库是空的,我们第一次推送master
分支时,加上了-u
参数,Git不但会把本地的master
分支内容推送的远程新的master
分支,还会把本地的master
分支和远程的master
分支关联起来,在以后的推送或者拉取时就可以简化命令。
推送成功后,可以立刻在GitHub页面中看到远程库的内容已经和本地一模一样:

从现在起,只要本地作了提交,就可以通过命令:
$ git push origin master
把本地master
分支的最新修改推送至GitHub,现在,你就拥有了真正的分布式版本库!
SSH警告
当你第一次使用Git的clone或者push命令连接GitHub时,会得到一个警告:
The authenticity of host 'github.com (xx.xx.xx.xx)' can't be established.
RSA key fingerprint is xx.xx.xx.xx.xx.
Are you sure you want to continue connecting (yes/no)?
这是因为Git使用SSH连接,而SSH连接在第一次验证GitHub服务器的Key时,需要你确认GitHub的Key的指纹信息是否真的来自GitHub的服务器,输入yes回车即可。
Git会输出一个警告,告诉你已经把GitHub的Key添加到本机的一个信任列表里了:
Warning: Permanently added 'github.com' (RSA) to the list of known hosts.
这个警告只会出现一次,后面的操作就不会有任何警告了。
2.从远程库克隆
现在,假设我们从零开发,那么最好的方式是先创建远程库,然后,从远程库克隆。
首先,登陆GitHub,创建一个新的仓库,名字叫Another-Test:

我们勾选
Initialize this repository with a README
,这样GitHub会自动为我们创建一个README.md
文件。创建完毕后,可以看到README.md
文件。现在,远程库已经准备好了,下一步是用命令
git clone
克隆一个本地库:
$ git clone git@github.com:HuskyFly/Another-Test.git
Cloning into 'Another-Test'...
Warning: Permanently added the RSA host key for IP address '192.30.255.113' to the list of known hosts.
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.
接着在本地的文件夹中,就可以看到README.md
文件;
接下来如果在文件夹中创建新的文件或者有其他操作,就可以将文件添加到暂存区,提交到本地库,然后推送到远程库了
$ git add Another-Test/*
$ git commit -m "添加文件"
$ git push -u origin master
网友评论