Git 常见问题

Git忽略规则及 .gitignore 规则不生效的解决办法

已知在 git 中如果想忽略掉某个文件,不让这个文件提交到版本库中,可以使用修改根目录中 .gitignore 文件的方法(如无,则需自己手工建立此文件)。

这个文件每一行保存了一个匹配的规则例如:

# 此为注释 – 将被 Git 忽略
*.a       # 忽略所有 .a 结尾的文件
!lib.a    # 但 lib.a 除外
/TODO     # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
build/    # 忽略 build/ 目录下的所有文件
doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt

规则很简单,不做过多解释,但是有时候在项目开发过程中,突然心血来潮想把某些目录或文件加入忽略规则,按照上述方法定义后发现并未生效,原因是 .gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改 .gitignore 是无效的。那么解决方法就是先把本地缓存删除(改变成未track状态),然后再提交:

git rm -r --cached .
git add .
git commit -m 'update .gitignore'

如果 cache 暂存区的内容和 HEAD 不一致,请使用: git rm rf --cache . 强制删除

Git 停止追踪文件权限

git config core.filemode false
cat .git/config

.gitkeep 有什么用?

“.gitkeep” isn’t documented, because it’s not a feature of Git.

Git cannot add a completely empty directory. People who want to track empty directories in Git have created the convention of putting files called “.gitkeep” in these directories. The file could be called anything; Git assigns no special significance to this name.

There is a competing convention of adding a “.gitignore” file to the empty directories to get them tracked, but some people see this as confusing since the goal is to keep the empty directories, not ignore them; “.gitignore” is also used to list files that should be ignored by Git when looking for untracked files.

or you can use like this to except for this one: !.gitignore.

git fetch repo 和 git fetch repo branch 的区别

git fetch, 理解 fetch 的含义, 是远程协作的关键,而理解 fetch 的关键, 是理解 FETCH_HEAD。

FETCH_HEAD 指的是: 某个 branch 在服务器上的最新状态。

每一个执行过 fetch 操作的项目,都会存在一个 FETCH_HEAD 列表,这个列表保存在 .git/FETCH_HEAD 文件中, 其中每一行对应于远程服务器的一个分支。

当前分支指向的 FETCH_HEAD, 就是这个文件第一行对应的那个分支。

一般来说, 存在两种情况:

1.如果没有显式的指定远程分支, 则远程分支的 master 将作为默认的 FETCH_HEAD。

2.如果指定了远程分支, 就将这个远程分支作为 FETCH_HEAD。

常见的 git fetch 使用方式包含以下四种:

  • git fetch

这一步其实是执行了两个关键操作:

1.创建并更新所有远程分支的本地远程分支。

2.设定当前分支的 FETCH_HEAD 为远程服务器的 master 分支 (上面说的第一种情况)。

需要注意的是,和 push 不同, fetch 会自动获取远程 新加入的分支。

  • git fetch origin

同上, 只不过手动指定了 remote。

  • git fetch origin branch1

设定当前分支的 FETCH_HEAD 为远程服务器的 branch1 分支。

注意: 在这种情况下, 不会在本地创建本地远程分支, 这是因为:

这个操作是 git pull origin branch1 的第一步, 而对应的 pull 操作,并不会在本地创建新的 branch。

一个附加效果是:这个命令可以用来测试远程主机的远程分支 branch1 是否存在, 如果存在, 返回0, 如果不存在, 返回128, 抛出一个异常。

  • git fetch origin branch1:branch2

只要明白了上面的含义, 这个就很简单了:

1.首先执行上面的 fetch 操作 2.使用远程 branch1 分支在本地创建 branch2 (但不会切换到该分支),如果本地不存在branch2分支, 则会自动创建一个新的 branch2 分支。

如果本地存在 branch2 分支, 并且是 fast forward,则自动合并两个分支, 否则, 会阻止以上操作.

  • git fetch origin :branch2

等价于: git fetch origin master:branch2。

  • git pull

只要理解了 git fetch, git pull就太简单了。

git pull 等价于以下两步:

1.经命令中的pull换成fetch, 执行之。

2.git merge FETCH_HEAD

唯一需要提及的一点是:

我认为 pull 操作, 不应该涉及三方合并 或 衍合 操作。

换个说法: pull 应该总是 fast forward 的. 为了达到这样一个效果, 在真正 push 操作之前, 我倾向于使用衍合, 在本地对代码执行合并操作。

关于 git 不区分文件名大小写的处理

今天遇到了 git 不区分文件名大小写的问题,一开始着实郁闷了一把。

处理办法:

windows 下在 git 中修改文件的大小写

git mv --force myfile MyFile

# 或者
git mv -f myfile MyFile

然后 commit 就好了。当然也可以配置一下 git:

Add ignorecase = false to [core] in .git/config;

其他

  • 创建版本号为 1 的 master 分支
git push sina master:1
  • 删除 master 分支上版本号为 1 的 代码
git push sina :1

# 或
git push sina master :1

有空格则为删除版本,无空格则为新建版本。

  • git push origin :branch

表示将一个内容为空的同名分支推送到远程的分支,说白了, 即删除远程主机的 branch 分支, 但是这并不会消除之前的 comment 内容, 而且你一旦提交了一些大的文件(例如: 图片之类的), 通过这个操作, 是不会将这些文件占用的空间消除的. 如果要真正的删除一个文件, 除了删除整个项目, Github网站也有提供办法。

参考

本文最后修改时间: 2016-02-12 17:32:55 +0000 (完) CC BY-NC-ND 3.0

若您发现文章中的错误,并愿告知于我,或想与我交流,我的联系方式在: Contacts


上一篇 关于电子信息工程

All The Best

下一篇 关于 "Hack"