git的使用

git的使用

introduction

git真的是个非常好的东西,特别是管理代码,我之前在大改代码之前都要复制一份,现在有了这个就非常的好用了。

  • 安装git 在linux上一般都有,没有的话 sudo apt-get install git
  • 然后设置, git config --global user.name "NAME" git config --global user.email "EMAIL"

上面的名字和email是github的email和用户名。也可以是其他的。

  • 创建repository,即建立版本库,这个里面的所有的东西会被git管理,还可以像时光穿梭机一样来回的在各个版本之间看。 具体操作是
    mkdir myfirst,
    cd myfirst,
    git init
    
  • git init 这个命令就会把这个myfirst目录变成git可以管理的仓库, 这时候myfirst里面已经有一个.git的目录了,用ls -lha 可以看到
  • 往里面加文件 假设里面有一个文件是hello.txt 内容是hello world!!! 这时候可以用 git add hello.txt 或者 git add . 也可以,因为这时候就只有这个hello.txt 然后要用 git commit -m “hello world!” -m是这次提交的说明,引号中的内容就是说明,说明这次提交的内容啊什么之类的,应该言简意赅。 注意如果一起加多个的话,可以 git add 1.txt 2.txt 也可连着用几个git add都可以,像这样 git add 1.txt git add 2.txt 3.txt

入正题

前面都是一些基本的使用,现在来重点了,会让人眼前一亮的东西,即time machine!

  • git status 这个命令是查看repository当前的状态,
  • git diff hello.txt 这个命令是查看difference,比如今天写完之后,放国庆假了,早已记不得节前干了啥,这时候就可以用这个命令来查看上次是做了什么改动。
  • 回到昨天 现在的问题是节前写了一大堆东西,节后的第一天头脑晕晨的写了很多的bug,现在想回到节前看一看那时候是写了啥,
  • git log 因为在实际中不可能都记得每次都瞎干了些什么,所以需要一个查看历史记录的东西,这就是git log 这个命令显示的里面最下面的是比较以前的,最上面的才是最近的。为了看着比较pretty的话,可以这样
  • git log –pretty=oneline 这里面会显示一些东西,其实那就是version id,
  • 回到之前的版本 git reset –hard HEAD^ 在git 里面HEAD表示的是当前的版本,上一个的话就是HEAD^,上上一个就是HEAD^^, 往上100个的话是这样HEAD~100 git reset –hard HEAD^ 就是回退到上一个版本。 这时候刚写的内容就会发现没有了,发现神奇的事情是现在看到的不就是节前写的东西吗,对,time machine起作用了,现在就是回到节前的状态了。这就是git的神奇的地方。
  • 再查看git log 刚才说不是回到节前了吗,现在查看git log的话, 发现并没有看到节后的版本,心里好难受,怕节后刚写的找不到了怎么办,其实没事儿的,解决办法有两个, 第一个是往上找,因为节后git的时候是有一个commit id的,只要找得到那个id就可以像这样 git reset –hard 789b…. 这里789b是前面的几个,只用输入前面的几个就可以了, 那现面万一服务器因为停电重启了咋办?当前的页面早没有了,这时候可以用
  • git reflog 试一下这个命令就可以看出来,这里面写的很明白,版本号也清晰,很容易找到节后commit的时候的id.
  • 为什么版本回退那么快 这个主要是因为HEAD其实是个指针,版本回退其实就是指针挪了下位置。

继续, working directory, stage, repository

working directory比较容易理解,即工作区,就是我现在正在写的目录myfirst,这里面有个.git 这个不算工作区, 而git的版本库(repository),看一个图,copy自峰哥的网站。 avator 其中stage就是暂存区,master是git为我们自动创建的第一个分支,以及指向Master的一个指针叫HEAD 那么我们之前的git add . 和git commit -m “hello world” 是做了什么呢? 实际上,git add 就是把文件添加进暂存区,而git commit 就是把暂存区的内容提交到当前的分支。 即整个过程可以理解为先放到暂存区,然后再从暂存区提交。

  • git 实际上管理的是修改,而不是文件, 比如 先写一个hello.txt git add 之后,又在里面写了一些东西,就git commit 了 那么这时候会看到第二次写的东西并没有显示,这是因为只有第一次的修改git add 了,第二次的修改并没有git add,所以为了都显示的话,就两次的都git add 这样就可以了。 即没有git add 的东西是没有进入到暂存区的。 而git commit 是将暂存区的内容提交,当如果没有进入暂存区自然太不会被提交了。
  • 撤销修改用git checkout – hello.txt 使用这个命令之后会将工作区的内容回到上一次使用git add 之后的状态。这显然包括了两种情况,一种是我这次还没有git add 那使用这个之后就会把我今天干的清0,回到昨天结束时的状态, 另一种状态是我今天已经git add 了, 然后我在没有git commit之前发现了一些bug,所以这时候使用完这个 git checkout – hello.txt 之后,就会回到我刚git add 之后的状态。 那么现在问题来了,我已经git add了,但是我发现今天写的全是bug,想回到git add前的状态,即把放到暂存区的内容也给清了回到工作区去。这时候可以用
  • git reset HEAD hello.txt

所以现在如果先git reset HEAD hello.txt 再git checkout – hello.txt的话就一下子回到了昨天结束时的状态了.

  • 册除操作 先是删除文件,即先在工作区删除 rm hello.txt 再在版本库中删除, git rm hello.txt 并且提交 git commit -m “delete hello.txt”
  • 误删除操作 先在工作区rm hello.txt了之后,发现自己手误删了重要的东西了怎么办,不用担心,即便自己的电脑上删了,版本库里面还是有的, 这时候还可以使用
  • git checkout – hello.txt 这个的作用是用版本库里的版本来替换工作区里的版本,注意到了无论是修改还是删除我们都可以用这个这命令进行还原。我是体会到了git的功能强大了!!!
  • 值得注意的是,误删除后恢复的文件是最新的版本,不能够知道最后一次提交的是啥修改内容。

远程

git 牛的地方还在于它是个分布式管理系统,即同一个git仓库可以分布到不同的机器上。别的机器只要clone就可以了。

  • 得有github账号
  • 创建ssh key 在~/.ssh/下面运行下面的命令

ssh-keygen -t rsa -C "email" 这个email也不一定得是github的email. 然后会产生id_rsa和id_rsa.pub, 前者是密钥,后者是公钥

  • 在github里面找到SSH keys的地方,点add ssh key,把id_rsa.pub的东西复制到里面去就可以了。
  • ssh key弄好之后,接下来就是在github上建立一个myfirst的resopority
  • 然后为了让两个实现同步,在本地的myfirst目录下运行
  • git remote add origin git@github.com:NAME/myfirst.git 其中的NAME是github上的名字 这里的origin就是远程库的名字,这是git 的默认的叫法,也可以改成其他的名字。
  • 把本地的东西推送到远程库上用下面这个命令
  • git push -u origin master 第一次的时候会用-u,因为那时候远程库是空的。之后就不用加 -u 了 之后 就可以git push origin master.

    当然上面是先有本地的,后有远程的,也可以是先有远程的,后有本地的,

    比如可以先在github上面建立一个,最后有初始化好的。 然后git clone + 地址 就可以了。 然后到本地的目录中就可以看到它了。

  • 现在有个问题是本地目录中也有了,他们同步了吗?现在在本地能够推送吗? 我自己试了下,好像不行,当git commit -m 的时候就有问题, 然后我按照下面的操作又可以了。 git init git add . git commit -m “ahha” git push origin master

    我现在有些迷糊为啥这里也可以用origin,我在另一个里面已经用了origin了。

    是在每个仓库里面都可以用origin吗,我猜应该是的,因为每个里面都有一个.git

    分支

    分支非常适合于多个人在共同完成同一个大的项目,每个人都在自己的分支下做自己的那部分活,然后最后在合并到一起就可以了。 大致过程是,先创建一个新的分支,然后在新的分支下完成某项子任务,之后在合主分支master进行合并,然后再删除掉新的分支,这样就相当于每个人做完了自己的工作,最后又合并到一起了。

  • master 分支 git会把每次提交的东西串成一条时间线,这条时间线就是一个分支,即master 分支,HEAD其实是指向master的,而master才是指向提交的,所以这样看的话就是HEAD指向当分支。
  • 每次提交master分支都会向前移动一步,这样master会越来越长

这里面的几个常用的命令

  • git checkout -b newbranch

‘-b’这个的意思是创建一个分支并切换至该分支,相当于 git branch newbranch git checkout newbranch

  • git branch

这个可以查看当前所有的分支,当前分支的前面会有一个*

当在新建的分支newbranch下干完了活儿之后,可以切换到主分支

  • git checkout master

然后再把newbranch分支的Job合并到master分支上面

  • git merge newbranch 意思是合并指定的分支到当前分支上面,因为当前的分支已经是master了(上一步已切换),所以现在就是合并到master上了。

合并完成之后,之前的分支newbranch可能没有多大用了,这时候可以删除了,

  • git branch -d newbranch

删除了之后可以再

git branch 

看一下,会发现这时候只有master分支了。

可能会发生冲突

刚才的情况是新建了一个分支newbranch之后,在newbranch下操作,操作完了之后和master合并,但是现在如果在newbranch下操作了之后,还没有和master合并的时候,先切换到master分支对master分支也作了修改,这时候再把newbranch分支合并给master的时候可能会出现冲突,在这种情况下可能需要手动来解决。

比如如可以用git status 查看冲突的文件,然后可以查看对应文件的内容,这时候手动更改我们希望的形式,然后再提交就可以了。 使用git log --graph --pretty=oneline --abbrev-commit可以看到分支的合并情况。然后确保已经是我们希望的形式了之后再删除newbranch分支 git branch -d newbranch. 其中的git log --graph可以看到分支的合并图。

多人协作

这里面涉及到的命令主要有

  • git remote 或 git remote -v

作用是查看远程库的信息 git remote -v 之后显示的是这样子的 avator 其中一个是可以fetch抓取的一个是可以push推送的。

  • 推送分支 git push origin branch-name推送的时候 要指定本地分支,这样git就会把该分支推送到远程库对应的远程分支上面去。

  • 不是每个分支都必要送到远程,有些是可以放在本地的。

现在假设远程有一个master分支,和一个分支叫做 mxnet,这两个分支在本地A电脑上都有, 那么我如果想要在另一台电脑B上也能够操作mxnet这个分支的话,我就要先clone这个库到本地B,但是此时本地B只能够看到master分支,可以用git branch看一下, 这时候需要在本地B 创建远程分支origin的mxnet分支到本地,使用命令

  • git checkout -b mxnet origin/mxnet

那么现在我就可以在本地B进行关于mxnet的玩耍了,还可以不断地进行推送到远程,但是要注意这时候我要推送到远程的时候,万一我的另一个本地A之前也对同样的文件作了修改,并且已经推送到了远程。那我再推送的时候该怎么办呢,这时候需要做的事情是先把远程最新的推送拉到本地B, 让这两个”mxnet”进行一个合并,合并完了之后再从本地B推送到远程。即有冲突了,拿到本地解决冲突,冲突解决完了之后再推送。 拉回本地用到的是git pull,但是这个使用之前要先指定本地的mxnet分支与远程的origin/mxnet分支的一个Link,

  • git branch --set-upstream-to=origin/mxnet mxnet

不然怎么会知道他们两个其实是同一个分支,只不过一个在远程一个在本地B呢,同样本地A也是需要做这一步的,即只要想从远程pull到本地都要做这个。

然后再git pull就会试图让两个合并,如果有冲突就手动解决。

之后 再git push origin mxnet 注意库的名字仍是origin, 分支是本地要推送的分支mxnet。

自己尝试了一个如果另外一台电脑没有加SSH-keys的话,推送的时候会显示要推送github的名字和密码,我加了SSH-keys之后,还是要密码和名字,是不是因为我推送的是master分支啊?但是我从A本地推送的时候就不需要密码啊。

打赏,谢谢~~

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,多谢支持~

打开微信扫一扫,即可进行扫码打赏哦