Git+GitHub,构建自己的开源仓库之Git踩过的坑

作者: 星际之痕 | 来源:发表于2016-07-20 00:05 被阅读807次

    俗话说:世上本没有坑,踩得人多了,也就有了坑......

    接触Git已经有一段时间了,也写了一些学习心得,这是第四篇关于Git的文章,记录一下在实践中踩过的坑。

    前三篇博文传送门:
    Git+GitHub,构建自己的开源仓库之Git分支
    Git+GitHub,构建自己的开源仓库之Git命令
    Git+GitHub,构建自己的开源仓库之初识Git

    希望我在学习中遇到的一些问题,同样能够帮助正在学习Git的你。
    下面是本文要介绍的Git操作(基于Git Bash命令行的操作):

    • 如何创建远程分支
    • 如何删除远程分支
    • 如何克隆远程分支
    • 如何添加、移除忽略文件
    • 添加、移除忽略文件不生效怎么回事
    • 删除的文件怎么恢复

    如何创建远程分支

    创建远程分支其实很简单,首先要在本地创建分支,然后把这个分支push到远程仓库。

    git branch -b develop_test
    git push origin develop_test
    

    这样,远程仓库就可以看见develop_test这个分支了。

    如何删除远程分支

    通过前面三篇文章的学习,相信都知道怎么删除本地分支了,这里回顾一下:

    git branch -d <name>
    git branch -D <name>--强制删除
    

    那么,对于远程仓库的分支,比如我的GitHub上的一个仓库,不小心push了一个没有什么意义的分支上去,怎么删除呢?

    git push origin :branch-name
    

    注意冒号前面的空格,意思是push一个空的分支到你要删除的那个分支上,相当于删除这个分支:

    $ git push origin :develop2
    To git@github.com:chengshengyang/Login-MVP-Architecture.git
       - [deleted]         develop2
    

    这对于删除tag同样有效,把要删除的分支名字换成对应的tag名字即可,在Git v1.7.0 之后,还可以使用这种语法删除远程分支:

    git push origin --delete <name>
    

    我们看看输出和上面的指令一个效果:

    $ git push origin --delete develop3
    To git@github.com:chengshengyang/Login-MVP-Architecture.git
     - [deleted]         develop3
    

    然后我GitHub上的develop2和develop3都被删掉了。

    如何克隆远程分支

    场景是我在A电脑上创建了一个分支develop,现在我回到家里,在自己的B电脑上要把这个develop分支clone下来,在本地做开发,这样,我上班有空了可以在公司电脑上倒腾自己的代码,下班前提交到develop,回家把在公司提交的代码pull下来,就不用电脑整天背来背去了。so easy!!!

    git clone默认会把远程仓库整个clone下来,但只会在本地默认创建一个master分支。想要clone其他分支,可以使用checkout命令来把远程分支取到本地,并自动建立tracking:

    git checkout -b develop origin/develop
    

    尝试输入上面命令,把develop克隆到本地,但是失败了:

    $ git checkout -t origin/develop
    fatal: Cannot update paths and switch to branch 'develop' at the same time.
    Did you intend to checkout 'origin/develop' which can not be resolved as commit?
    

    git remote show origin命令查看一下远程仓库的状态:

    $ git remote show origin
    * remote origin
      Fetch URL: git@github.com:chengshengyang/Login-MVP-Architecture.git
      Push  URL: git@github.com:chengshengyang/Login-MVP-Architecture.git
      HEAD branch: master
      Remote branches:
        develop new (next fetch will store in remotes/origin)
        master  tracked
      Local branch configured for 'git pull':
        master merges with remote master
      Local ref configured for 'git push':
        master pushes to master (local out of date)
    

    可以看到develop分支的状态是new,而不是跟master分支一样:tracked。这就是导致问题的原因。也就是说develop分支还没有被追踪。执行git remote update命令:

    $ git remote update
    Fetching origin
    remote: Counting objects: 81, done.
    remote: Compressing objects: 100% (28/28), done.
    remote: Total 81 (delta 21), reused 12 (delta 12), pack-reused 37
    Unpacking objects: 100% (81/81), done.
    From github.com:chengshengyang/Login-MVP-Architecture
       db7e7b3..82618ec  master     -> origin/master
     * [new branch]      develop    -> origin/develop
    

    再调用git remote show origin命令查看

    $ git remote show origin
    * remote origin
      Fetch URL: git@github.com:chengshengyang/Login-MVP-Architecture.git
      Push  URL: git@github.com:chengshengyang/Login-MVP-Architecture.git
      HEAD branch: master
      Remote branches:
        develop tracked
        master  tracked
      Local branch configured for 'git pull':
        master merges with remote master
      Local ref configured for 'git push':
        master pushes to master (local out of date)
    

    这时候develop分支也变成了tracked了,接着执行git fetch命令,无任何输出(成功)。问题解决。再次执行克隆远程分支命令

    $ git checkout -b develop origin/develop
    error: Your local changes to the following files would be overwritten by checkout:
            .idea/misc.xml
    Please commit your changes or stash them before you can switch branches.
    Aborting
    

    提示本地分支有未提交的内容,先提交,保持工作空间的clean。

    chengshengyang@csy-pc MINGW64 ~/AndroidStudioProjects/Login-MVP-Architecture (master)
    $ git checkout -b develop origin/develop
    Branch develop set up to track remote branch develop from origin.
    Switched to a new branch 'develop'
    
    chengshengyang@csy-pc MINGW64 ~/AndroidStudioProjects/Login-MVP-Architecture (develop)
    

    ok,终于成功啦,现在我在本地克隆了远程仓库的develop分支,并且切换到develop分支了。

    $ git branch
    * develop
      master
    

    上述问题的解决方案参考:

    如何添加、移除忽略文件

    添加删除忽略文件都是对.gitignore进行编辑,对于ignore的语法,可以通过Android Studio的“.ignore”插件来学习,这个插件还挺好用的,会教你怎么来写忽略文件,而且会把忽略文件灰色标记,一目了然。

    设置忽略规则 忽略插件

    忽略文件配置示例:

    # 用'#'开始注释一行. 
    
    # 忽略掉所有文件名是 foo.txt 的文件.
    foo.txt
    
    # 忽略所有生成的 html 文件,
    *.html
    # foo.html是个特例,不添加忽略.
    !foo.html
    
    # 忽略所有.o和 .a文件,出了special.o文件.
    *.[oa] 
    !special.o
    
    # 只忽略当前目录下的folder文件和目录,子目录的folder不在忽略范围内
    /folder
    
    # 只忽略test文件,不忽略test目录(比如当前目录下有test文件夹、test.jpg、test.png等)
    test
    !test/
    
    # 只忽略test目录,不忽略test文件
    test/
    
    # 忽略test文件和test目录
    test
    

    添加、移除忽略文件不生效怎么回事

    辛辛苦苦编辑完忽略规则,却发现设置的规则完全没起作用,或者有的起作用了,有的没起作用,怎么回事?原因是.gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。解决方法就是先把要忽略文件的本地缓存删除(改成未track状态),然后再修改提交.gitignore文件:

    git rm -r --cached .idea/modules.xml
    git add .gitignore
    git commit -m 'update .gitignore'
    

    关于忽略可以参考:https://github.com/github/gitignore 来设置忽略规则。

    删除的文件怎么恢复

    最怕的就是文件误删,吓尿了,怎么办?不要怕,在Git里,永远有后悔药可以吃。

    • 1.远程仓库没删除,本地执行了add 和 commit,这种情况下,恢复删除文件很简单:

        git checkout -- test.txt
      

    文件就恢复到仓库的最新版本了,可能会丢失上次push后的一些修改。

    • 2.远程仓库都没啦,本地删除后push到远程了。这种情况,可以从本地的版本恢复,先用git log 查看提交的记录,找到被删除之前的一个commit-id,拷贝,

        git checkout commit_id -- path_to_file
      

    把文件恢复到版本commit-id。

    • 3.如果要查看删除的文件:

        git ls-files --deleted
      

    要恢复则需要执行checkout:

    git checkout – <deleted_file>
    

    多个文件同时操作可以使用xargs:

    git ls-fies -d | xargs git checkout --
    

    总结

    Git的内容还是很多的,用法也多种多样,很多操作可能不止一种写法,各个版本也有所不同,学习起来很容易入坑,遇到问题的解决方法也不是唯一的,关键是每个命令的实现原理,学习Git不能只关注各种命令,更重要的其实是原理,基友们学习的时候要抓住重点,注重基础原理的理解。

    相关文章

      网友评论

        本文标题:Git+GitHub,构建自己的开源仓库之Git踩过的坑

        本文链接:https://www.haomeiwen.com/subject/cbhvjttx.html