git及github使用记录

1.Git简介

Git是Linux之父Linus的第二个伟大的作品,它最早是在Linux上开发的,被用来管理Linux核心的源代码。后来慢慢地有人将其移植到了Unix、Windows、Max OS等操作系统中。

Git是一个分布式的版本控制系统,与集中式的版本控制系统不同的是,每个人都工作在通过克隆建立的本地版本库中。也就是说每个人都拥有一个完整的版本库,查看提交日志、提交、创建里程碑和分支、合并分支、回退等所有操作都直接在本地完成而不需要网络连接。

对于Git仓库来说,每个人都有一个独立完整的仓库,所谓的远程仓库或是服务器仓库其实也是一个仓库,只不过这台主机24小时运行,它是一个稳定的仓库,供他人克隆(clone)、推送(push),也从服务器仓库中拉取别人的提交(pull)。Git是目前世界上最先进的分布式版本控制系统。

git_three_rigon.png-212.9kB

工作区(working diretory) 用于修改文件
缓存区(stage) 是用来暂时存放工作区中修改的内容
提交历史(commit history) 提交代码的历史记录

主要的几个命令
git add # 将工作区的修改提交到暂存区
git commit # 将暂存区的修改提交到当前分支
git reset # 回退到某一个版本
git stash # 保存某次修改
git pull # 从远程更新代码
git push # 将本地代码更新到远程分支上
git reflog # 查看历史命令
git status # 查看当前仓库的状态
git diff # 查看修改
git log # 查看提交历史
git revert # 回退某个修改

2.git客户端下载与安装

        1)官网下载:http://git-scm.com/download/win

      由于 Git for Windows.国内直接从官网下载比较困难,需要翻墙。这里淘宝提供一个国内的下载站,方便下载:

      https://npm.taobao.org/mirrors/git-for-windows/

       2) git客户端安装

         参考如下:https://blog.csdn.net/q563573095/article/details/79558067

3.git相关命令详解

1)git add

删除文件后需要 git add -A, 光 git add . 不行,区别如下:

git add -A 保存所有的修改
git add .   保存新的添加和修改,但是不包括删除
git add -u 保存修改和删除,但是不包括新建文件。
所以默认使用git add -A就行

2)git commit

git commit 主要是将暂存区里的改动给提交到本地的版本库。每次使用git commit 命令我们都会在本地版本库生成一个40位的哈希值,这个哈希值也叫commit-id,commit-id在版本回退的时候是非常有用的,它相当于一个快照,可以在未来的任何时候通过与git reset的组合命令回到这里。

git commit –m “本次提交描述”

 该命令会将git add .存入暂存区修改内容提交至本地仓库中,若文件未添加至暂存区,则提交时不会提交任何修改。这种是比较常见的用法,-m 参数表示可以直接输入后面的“message”,如果不加 -m参数,那么是不能直接输入message的,而是会调用一个编辑器(一般是vim)来让你输入这个message,

message即是我们用来简要说明这次提交的语句。还有另外一种方法,当我们想要提交的message很长或者我们想描述的更清楚更简洁明了一点,我们可以使用这样的格式,如下:

        git commit -m ‘

        message1

        message2

        message3

        ’
git commit -a

相当于运行 git add -u把所有当前目录下的文件加入缓存区域再运行git commit。注意:对于新增的文件,并没有被commit

git commit –am “本次提交描述”

或者

git commit –a –m“本次提交描述”

等同于上面的-a和-m

git commit --amend  //也叫追加提交

修改最近一次提交。有时候如果提交注释书写有误或者漏提文件,可以使用此命令。对于漏提交的文件,需要git add到缓存区之后,git commit --amend才能将修改追加到最近的一次提交上。

即如果我们不小心提交了一版我们不满意的代码,并且给它推送到服务器了,在代码没被merge之前我们希望再修改一版满意的,而如果我们不想在服务器上abondon,可以通过上述命令在不增加一个新的commit-id的情况下将新修改的代码追加到前一次的commit-id中。

3)git reset

git reset根据--soft --mixed --hard,会对working tree和index和HEAD进行重置

$ git reset HEAD^

回退版本,一个^表示一个版本,可以多个,另外也可以使用 git reset HEAD~n这种形式。
也可以回退到指定版本:

$ git reset commit-id

soft 参数:git reset --soft HEAD~1 意为将版本库软回退1个版本,所谓软回退表示将本地版本库的头指针全部重置到指定版本,且将这次提交之后的所有变更都移动到暂存区

默认的mixed参数:git reset HEAD~1 意为将版本库回退1个版本,将本地版本库的头指针全部重置到指定版本,且会重置暂存区,即这次提交之后的所有变更都移动到工作区

hard参数:git reset --hard HEAD~1 意为将版本库回退1个版本,但是不仅仅是将本地版本库的头指针全部重置到指定版本,也会重置暂存区,并且会将工作区代码清空(工作区是clean状态)

注意,soft参数与默认参数都不会修改工作区代码,只有hard参数才会修改工作区代码。

另外,git reset HEAD filename
回退文件,将文件从暂存区回退到工作区(unstage),此时不能带hard,soft参数

4)git reflog

如果在回退以后又想再次回到之前的版本,git reflog 可以查看所有分支的所有操作记录(包括commit和reset的操作),包括已经被删除的commit记录,git log则不能察看已经删除了的commit记录

615ce06 HEAD@{44}: rebase -i (finish): returning to refs/heads/my_test_branch
615ce06 HEAD@{45}: rebase -i (fixup): zancun_new
702356c HEAD@{46}: rebase -i (fixup): # This is a combination of 2 commits.
c997622 HEAD@{47}: rebase -i (reword): zancun_new
fb74ec2 (origin/master, origin/HEAD) HEAD@{48}: rebase -i (start): checkout FETCH_HEAD
f3ef592 HEAD@{49}: commit: zancun3
6b82c75 HEAD@{50}: commit: zancun2
e900fa0 HEAD@{51}: commit: zancun

比如说,回退到commit: zancun3,只需要:
git reset --hard f3ef592 (或者HEAD@{49}) 即可
这个命令对于找回丢失的代码非常有用。

5)删除分支

删除分支:

 $ git branch -d branchName


或者, git branch -D branchName 删除分支(不管它有没有merge)
前提是先要切换到其他分支

$ git branch -d branch1
error: The branch ‘branch1’ is not fully merged.
If you are sure you want to delete it, run ‘git branch -D branch1’.

6)git push

git push命令用于将本地分支的更新,推送到远程主机。

$ git push <远程主机名> <本地分支名>:<远程分支名>
$ git push origin master

上面命令表示,将本地的master分支推送到origin主机的master分支。如果master不存在,则会被新建。

如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。

$ git push origin :master
# 等同于
$ git push origin --delete master

上面命令表示删除origin主机的master分支。如果当前分支与远程分支之间存在追踪关系,则本地分支和远程分支都可以省略。

 $ git push origin

上面命令表示,将当前分支推送到origin主机的对应分支。如果当前分支只有一个追踪分支,那么主机名(设置了默认主机)都可以省略。

$ git push

如果当前分支与多个主机存在追踪关系,则可以使用-u选项指定一个默认主机,这样后面就可以不加任何参数使用 git push推送。

$ git push -u origin master

上面命令将本地的master分支推送到origin主机,同时指定origin为默认主机,后面就可以不加任何参数使用 git push了。

将当前分支推送到远程的同名的简单方法,如下:

$ git push origin HEAD

将当前分支推送到源存储库中的远程引用匹配主机。 这种形式方便推送当前分支(HEAD相当于当前分支的占位符),而不考虑其本地名称。HEAD概念详解:https://www.cnblogs.com/runnerjack/p/9342362.html

如下:

$ git push origin HEAD:master

单独使用git push时,没有指定push的remote分支名,假如当前本地分支名称与其对应的remote分支名称不一样,则会有如下提示:

fatal: The upstream branch of your current branch does not match
the name of your current branch.  To push to the upstream branch
on the remote, use
    git push origin HEAD:my_new_test_branch
To push to the branch of the same name on the remote, use
    git push origin test
To choose either option permanently, see push.default in 'git help config'.

7)git pull

git pull命令用于从另一个存储库或本地分支获取并集成(整合)。git pull命令的作用是:取回远程主机某个分支的更新,再与本地的指定分支合并。

$ git pull <远程主机名> <远程分支名>:<本地分支名>

比如,要取回origin主机的master分支,与本地的test分支合并,需要写成下面这样

$ git pull origin master:test

如果远程分支(master)要与本地当前分支合并,则冒号后面的部分可以省略。上面命令可以简写:

$ git pull origin master

将远程存储库中的更改合并到当前分支中。在默认模式下,git pull是git fetch后跟git merge FETCH_HEAD的缩写。

更准确地说,git pull使用给定的参数运行git fetch,并调用git merge将检索到的分支头合并到当前分支中。 使用–rebase,它运行git rebase而不是git merge。也就是说

git pull = git fetch + git merge
git pull --rebase = git fetch + git rebase

git fetch将远程主机的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中。

而git pull则是将远程主机的最新内容拉下来后直接合并,即:git pull = git fetch + git merge,这样可能会产生冲突,需要手动解决。

git pull中fetch命令是将远程分支的最新内容拉到了本地,但是fetch后是看不到变化的,此时本地多了一个FETCH_HEAD的指针,checkout到该指针后可以查看远程分支的最新内容。然后checkout到master分支,执行merge,选中FETCH_HEAD指针,合并后如果出现冲突则需要手动解决冲突。

什么是冲突

合并的时候,有可能会产生冲突。冲突的产生是因为在合并的时候,不同分支修改了相同的位置。所以在合并的时候git不知道那个到底是你想保留的,所以就提出疑问(冲突提醒)让你自己手动选择想要保留的内容,从而解决冲突。

git merge和 git rebase

1)git merge

将 origin 分支合并到 mywork 分支最简单的办法就是用下面这些命令

git checkout mywork
git merge origin

或者,也可以把它们压缩在一行里:

git merge origin mywork

假设远程分支上有3次提交A,B,C:

                                
在远程分支origin的基础上创建一个名为"mywork"的本地分支并提交了修改E,同时有其他人在"origin"上做了一些修改并提交了修改D。

                         image_1chevnkgpshs17133n5bqrfpjt.png-20.6kB
用git merge命令把"origin"分支与本地提交合并(merge)成版本M,mywork 分支中新的合并提交(merge-commit)将两个分支的历史连在了一起,但这样会形成图中的菱形,让人很困惑。

                    image_1chevr3p71knutjj1lv3f4e5391a.png-26kB
Merge 好在它是一个安全的操作,比较安全,现有的分支不会被更改,避免了 rebase 潜在的缺点(后面会说)。另一方面,这同样意味着每次合并上游更改时 feature 分支都会引入一个外来的合并提交。如果 master非常活跃的话,这或多或少会污染你的分支历史。虽然高级的 git log 选项可以减轻这个问题,但对于开发者来说,还是会增加理解项目历史的难度。

2)git rebase

作为 merge 的替代选择,rebase可以像下面这样将 mywork 分支并入 origin 分支:

git checkout mywork
git rebase origin

它会把整个 mywork 分支移动到 origin 分支的后面,有效地把所有 master 分支上新的提交并入过来。但是,rebase为原分支上每一个提交创建一个新的提交,重写了项目历史,并且不会带来合并提交。rebase的好处是避免了菱形的产生,保持提交曲线为直线,让大家易于理解。

                                    image_1chip8e1b1t1vo01m3t1g2bne91u.png-26.2kB
rebase最大的好处是你的项目历史会非常整洁。首先,它不像 git merge 那样引入不必要的合并提交。其次,如上图所示,rebase 导致最后的项目历史呈现出完美的线性——你可以从项目终点到起点浏览而不需要任何的 fork。这让你更容易使用 git log、git reset 和 gitk 来查看项目历史。

不过,这种简单的提交历史会带来两个后果:安全性和可跟踪性。如果你违反了 rebase 黄金法则,重写项目历史可能会给你的协作工作流带来灾难性的影响。此外,rebase 不会有合并提交中附带的信息——你看不到 mywork 分支中并入了上游的哪些更改。

在rebase的过程中,有时也会有conflict,这时Git会停止rebase并让用户去解决冲突,解决完冲突后,用git add命令去更新这些内容,然后不用执行git commit,直接执行git rebase --continue,这样git会继续apply余下的补丁。
在任何时候,都可以用git rebase --abort参数来终止rebase的行动,并且mywork分支会回到rebase开始前的状态。

官方的两张merge和rebase对比图:

merge示例图:

屏幕快照 2018-09-21 下午11.01.48.png-126kB

rebase示例图:

rebase_wrong.png-150.4kB

3)rebase的高级操作–交互式rebase

交互式的 rebase 允许你更改并入新分支的提交。这比自动的 rebase 更加强大,因为它提供了对分支上提交历史完整的控制。一般来说,这被用于将 feature 分支并入 master 分支之前,清理混乱的历史。

把 -i 传入 git rebase 选项来开始一个交互式的rebase过程:

git checkout feature
git rebase -i master

它会打开一个文本编辑器,显示所有将被移动的提交:

pick e900fa0 zancun
pick 6b82c75 zancun2
pick f3ef592 zancun3

# Rebase fb74ec2..f3ef592 onto fb74ec2 (3 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

这个列表定义了 rebase 将被执行后分支会是什么样的。更改 pick 命令或者重新排序,这个分支的历史就能如你所愿了。比如说,如果第二个和第三个提交只是修复了第一个提交中的小问题,你可以用 fixup 命令把它们合到第一个提交中,并修改第一个的日志:

r e900fa0 zancun
f 6b82c75 zancun2
f f3ef592 zancun3

这样三个提交合并成了一个提交,并可以重新修改提交日志,非常实用。
忽略不重要的提交会让你的 feature 分支的历史更清晰易读。这是 git merge 做不到的。

4)Rebase的黄金法则

当你理解rebase是什么的时候,最重要的就是什么时候不能用rebase。git rebase 的黄金法则便是,绝不要在公共的分支上使用它

比如说,如果你把 master分支rebase到你的feature 分支上会发生什么:

rebase_wrong.png-150.4kB
这次 rebase 将 master 分支上的所有提交都移到了 feature 分支后面。问题是它只发生在你的代码仓库中,其他所有的开发者还在原来的 master 上工作。因为 rebase 引起了新的提交,Git 会认为你的 master 分支和其他人的 master 已经分叉了。

同步两个 master 分支的唯一办法是把它们 merge 到一起,导致一个额外的合并提交和两堆包含同样更改的提交。不用说,这会让人非常困惑。

所以,在你运行 git rebase 之前,一定要问问你自己「有没有别人正在这个分支上工作」。如果答案是肯定的,那么把你的爪子放回去,重新找到一个无害的方式(如 git merge)来提交你的更改。不然的话,你可以随心所欲地重写历史。

4.github使用场景

1)上传本地项目到github库中步骤可参考: https://blog.csdn.net/Lucky_LXG/article/details/77849212

                                                                 https://www.cnblogs.com/mr-wuxiansheng/p/6974170.html

第一次创建仓库并上传github命令如下:

echo "# test" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/Sniperliangzhu/test.git
git push -u origin master

push已存在的repository到远程仓库(github)命令如下:

git remote add origin https://github.com/Sniperliangzhu/test.git
git push -u origin master

2)本地创建分支并提交到github参考:https://blog.csdn.net/daerzei/article/details/79530418

5.参考文档

https://blog.csdn.net/weelyy/article/details/82823798#t8

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章