$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"
$ git init
//把某个目录变成Git可以管理的仓库
$ git add <文件名>
//用命令git add告诉Git,把文件添加到仓库Git添加
文件需要add,commit一共两步呢?因为commit可以一次提交很多文件,所以你可以多次add不同的文件,比如:
$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."
git add *
添加所有修改文件到暂存区
git add
添加某个文件到暂存区
git commit -m "自定义记录"
提交暂存区的修改到版本库
第一步是用git add
把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit
提交更改,实际上就是把暂存区的所有内容提交到当前分支。
git status
命令可以让我们时刻掌握仓库当前的状态Untracked
这三个分别是:
第一个是add之后但是没有commit的
第二个是没有add的
第三个是新文件,未被追踪的
####1.4 git push
git push
:更新本地git版本库到remote版本库:git push origin master
:将本地的master分支推送到origin
主机的master
分支。如果master
不存在,则会被新建。git push origin master --force
:表示将本地版本库强制推到远程版本库,该操作比较危险,如果不是很有把握,一定不要这么做git diff
这里显示的是本地没有提交的和提交的版本上的差异,显示的格式正是Unix通用的diff格式
git log
命令显示从最近到最远的提交日志
git log --pretty=oneline
显示一行
git log --graph
分支合并图
git log --pretty=oneline
分支合并图 每个一行显示
git reset --hard HEAD^
首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交3628164…882e1e0(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD,上上一个版本就是HEAD,当然往上100个版本写100个比较容易数不过来,所以写成HEAD~100。
命令执行后会提醒:
Unstaged changes after reset:
M README.md
这里直接把head指针修改了,但是文件的内容没有修改,需要借助1.7小节命令将其工作区的文本文件还原(具体原理见1.6),通过git status可查看,直接checkout就可以将文本变为想还原的版本了
后悔了,还想找到最新的怎么办呢?
办法其实还是有的,只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找到那个append GPL的commit id是3628164…,于是就可以指定回到未来的某个版本:
git reset --hard 3628164
Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向append GPL:
改为指向add distributed:
然后顺便把工作区的文件更新了。所以你让HEAD指向哪个版本号,你就把当前版本定位在哪。
想恢复到新版本怎么办?找不到新版本的commit id怎么办?
在Git中,总是有后悔药可以吃的。当你用$ git reset --hard HEAD^回退到add distributed版本时,再想恢复到append GPL,就必须找到append GPL的commit id。Git提供了一个命令git reflog用来记录你的每一次命令
$ git reflog
a4a4527 (HEAD -> master, origin/master) HEAD@{0}: reset: moving to a4a45
dae796b HEAD@{1}: reset: moving to HEAD^
a4a4527 (HEAD -> master, origin/master) HEAD@{2}: commit: the third times modify readme.md
dae796b HEAD@{3}: commit: modify readme.md & add test2.txt
bdacecc HEAD@{4}: commit: new file readme.md
76b4650 HEAD@{5}: commit (initial): my first test
注意这里前面的那个id就是后面命令执行后最新的版本号,所以就可以回到最新的了
github怎么提交回退旧版本代码并更改后的文件到主分支上? (原文链接)
可能说的不是很明白,就是我代码写着写着,发现我已经不想这么弄了,用git reset --hard <版本号>退回到之前的某个版本重新写,这样当我当我写完之后,想在提交到远程仓库,它就会报错:
To https://github.com/zifenggao/wenda.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to ‘https://github.com/zifenggao/wenda.git’
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: ‘git pull …’) before pushing again.
hint: See the ‘Note about fast-forwards’ in ‘git push --help’ for details.
首先,根据你的描述,既然你用到了git reset --hard
,那就可以推断出你已经add
和commit
过了。
其次,根据报错,可以推断出你已经push
过了(这个推断基于只有你一个人拥有master branch
的更改权限。
那么当你执行git reset --hard
之后,历史纪录是不能跟远程的记录直接合并的。因此才会有这个报错。
举个例子,远程是A -> B -> C -> D
,你git reset --hard
之后是A -> B
。这时候除非远程那边抹掉 C 和 D,否则是不能合并的。
因此,这时候,你应该使用git push origin master --force
来强行覆盖远程记录。
请不要根据提示使用git pull
。否则,你的本地又会变成A -> B -> C -> D
。因为git pull
相当于git fetch + git merge
(以下内容基于上面的例子,远程是A -> B -> C -> D
,你想回滚到 B 那个状态)
楼上提到了git revert
。其实,git reset --hard
和git revert
都可以实现“回滚代码”。但区别在于:
git revert
会把你的本地变成A -> B -> C -> D -> E
。其中,E 干的事儿是删除 C 和 D。这样做的好处在于,你git push origin master
就不会有上面的报错了。但,历史线上还是会保留 C 和 D 这两个commit
。如果使用这个命令,记得要add
然后commit
。
git reset --hard
会直接删掉 C 和 D,形成 A -> B 这样的结果。好处在于更直接更彻底。缺点在于,首先要通过git push origin master --force
去强行更改。其次,一旦你后悔了,除非根据本地的 reflog 直接恢复 HEAD 指针,此外没有其他办法。
用哪个都是没错的,请根据自己的需要来选择。
命令git checkout -- readme.txt
意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
总之,就是让这个文件回到最近一次git commit
或git add
时的状态。
使用场景:
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout – file。
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。
删除文件:
$ git rm test.txt
$ git commit -m "remove test.txt"
查看remote名称,增加-v可查看详细信息
廖雪峰“说”:
分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。
现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
其他版本控制系统如SVN等都有分支管理,但是用过之后你会发现,这些版本控制系统创建和切换分支比蜗牛还慢,简直让人无法忍受,结果分支功能成了摆设,大家都不去用。
但Git的分支是与众不同的,无论创建、切换和删除分支,Git在1秒钟之内就能完成!无论你的版本库是1个文件还是1万个文件。
每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。
一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点
而增加分支就相当于增加新的dev指针(详情)
-b参数表示创建并切换 :$git checkout -b dev
,上面相当于:git branch dev
和git checkout dev
回到master分支: $ git checkout master
切换分支:git checkout
创建+切换分支:git checkout -b
git branch
命令会列出所有分支,当前分支前面会标一个*号。
git branch
创建分支
git branch -d
删除分支
git merge
合并某分支到当前分支 --no-ff
表示禁用fast forward
更多分支相关的问题参见Git 分支 - 分支的新建与合并
git pull
相当于git fetch
+git merge
####2.4 远程git分支创建(如GitHub)
git push --set-upstream origin <分支名称>
远程创建分支,不过这里需要在本地存在已经创建的分支,说白了这个命令是将本地的分支push到远程版本库
正常情况下,我们可能不会显式的创建分支,但是在merge的时候其实实质上还是会用到分支的知识,下面介绍几种情形。
我们的代码从远程版本库clone之后,在我们修改的同时,别人已经先人一步提交他们的代码,这样我们再提交的时候,就会出现两种情况:
我们修改的文件别人没有修改过,这个时候我们就可以通过两种方式进行merge:
(当然对于这种情况还是推荐用第一种方式,因为用第二种方式的时候会多出一个版本来,多多少少有点乱)
我们修改的文件别人已经修改过,提交到了远程仓库,这个时候再使用git pull
就会报下面的错误了:
所以说上面的第一种方法失效,针对这种情况,我们只能通过一种方式进行解决了,流程和上面一种情况的方法二一样,只不过因为存在文件冲突,需要手动解决掉冲突然后在push:
先用git add
和git commit
命令在本地创建版本,然后再git pull,对于出现文本冲突的文档,手动选择修改,然后填写好merge日志之后就可以再次push了。详情如下:
这里大家会看到冲突的文件发生了变化,下面详细说下冲突文件出现变化的语法现象:
上图中被红框标记的部分,前两个红框之间的部分,是本地的内容。
后两个红框之间的部分,是origin/master远端的内容。怎么修改决定于你。但是最后要把红框红的内容删除
综上,我们再做工程的时候,因为不知道本地修改的代码是在哪个基础上修改的,所以在提交的时候先git pull 一下:
git pull
自动就merge了)Git有commit,为什么还要引入tag?
“请把上周一的那个版本打包发布,commit号是6a5819e…”
“一串乱七八糟的数字不好找!”
如果换一个办法:
“请把上周一的那个版本打包发布,版本号是v1.2”
tag应运而生!!!
git tag v1.0 //默认标签是打在最新提交的commit上的。
git tag -a -m "blablabla..."//可以指定标签信息;
git tag v0.9 6224937 //提交打标签,对应的commit id是6224937
git tag //查看所有标签
git show v0.9 //查看标签信息
git tag -d v0.1 //删除标签
git push origin v1.0 //推送本地v1.0标签到远程
git push origin --tags //推送本地所有标签到远程
/*远程删除tag,先在本地删除,再删除远程(好像直接远程也可以吧)*/
git tag -d v0.9
git push origin :refs/tags/v0.9
绑定自己的账号和公开自己起的名字
$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"
Git显示颜色,会让命令输出看起来更醒目
$ git config --global color.ui true
echo "# sss" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/zsweet/xxx.git
git push -u origin master
添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
从现在起,只要本地作了提交,就可以通过命令:
$ git push origin master
//或者直接 git push
git remote add origin https://github.com/zsweet/xxx.git
git push -u origin master
克隆远程git到本地,两种方式都可以:我常用第二个
$ git clone [email protected]:michaelliao/gitskills.git
$ git clone https://github.com/michaelliao/gitskills.git
参考:
彻底删除git中没用的大文件
寻找并删除Git记录中的大文件