分类 git 下的文章

使用git Rebase让历史变得清晰,合并git历史

当多人协作开发一个分支时,历史记录通常如下方左图所示,比较凌乱。如果希望能像右图那样呈线性提交,就需要学习git rebase的用法。

“Merge branch”提交的产生

我们的工作流程是:修改代码→提交到本地仓库→拉取远程改动→推送。正是在git pull这一步产生的Merge branch提交。事实上,git pull等效于get fetch origin和get merge origin/master这两条命令,前者是拉取远程仓库到本地临时库,后者是将临时库中的改动合并到本地分支中。

要避免Merge branch提交也有一个“土法”:先pull、再commit、最后push。不过万一commit和push之间远程又发生了改动,还需要再pull一次,就又会产生Merge branch提交。

使用git pull –r
修改代码→commit→git pull –rebase→git push 也就是将git merge origin/master替换成了git rebase origin/master,它的过程是先将HEAD指向origin/master,然后逐一应用本地的修改,这样就不会产生Merge branch提交了。具体过程见下文扩展阅读。

使用git rebase是有条件的,你的本地仓库要“足够干净”。可以用git status命令查看当前改动::

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

本地没有任何未提交的改动,这是最“干净”的。稍差一些的是这样:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    test.txt
nothing added to commit but untracked files present (use "git add" to track)

即本地只有新增文件未提交,没有改动文件。我们应该尽量保持本地仓库的“整洁”,这样才能顺利使用git rebase。特殊情况下也可以用git stash来解决问题,有兴趣的可自行搜索。

修改git pull的默认行为

每次都加–-rebase似乎有些麻烦,我们可以指定某个分支在执行git pull时默认采用rebase方式:

$ git config branch.master.rebase true

如果你觉得所有的分支都应该用rebase,那就设置:

$ git config --global branch.autosetuprebase always

这样对于新建的分支都会设定上面的rebase=true了。已经创建好的分支还是需要手动配置的。

扩展阅读[1]:git rebase工作原理

在做项目开发时会用到分支,合并时采用以下步骤:

$ git checkout feature-branch
$ git rebase master
$ git checkout master
$ git merge --no-ff feature-branch
$ git push origin master

历史就成了这样:
转载自 http://www.cnblogs.com/UnGeek/p/5737653.html

git push 401错误,安装新版的git

解决git clone时报错:The requested URL returned error: 401 Unauthorized while accessing

版本问题,最直接的解决办法就是重新编辑安装git吧:

下载安装源码

下载:wget -O git.zip https://github.com/git/git/archive/master.zip
解压:unzip git.zip
进入git目录:cd git-master

编译安装:

autoconf
./configure --prefix=/usr/bin/git
make
/usr/bin/perl Makefile.PL PREFIX='/usr/bin' INSTALL_BASE='' --localedir='/usr/bin/share/locale'
Can't locate ExtUtils/MakeMaker.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at Makefile.PL line 3.
BEGIN failed--compilation aborted at Makefile.PL line 3.
make[1]: *** [perl.mak] 错误 2
make: *** [perl/perl.mak] 错误 2

make报错了,git 需要perl来编译。然后重新make执行如下

yum install perl-ExtUtils-MakeMaker package

再make,又报错

make
 tclsh failed; using unoptimized loading
    MSGFMT    po/bg.msg make[1]: *** [po/bg.msg] 错误 127
make: *** [all] 错误 2

执行如下

yum install tcl build-essential tk gettext

再make,遇到如下错误

In file included from credential-store.c:1:
cache.h:40:18: warning: zlib.h: No such file or directory
In file included from credential-store.c:1:
cache.h:42: error: expected specifier-qualifier-list before ‘z_stream’
make: *** [credential-store.o] Error 1

安装zlib和zlib-devel

yum install zlib zlib-devel -y

安装之后使用https操作git 出现 :fatal: Unable to find remote helper for 'https'</li>

yum install -y curl curl-devel`

然后重新安装 git

make install

最后别忘了删掉旧的git,并把新版本的git建立软链接到 /usr/local/bin/git

ln -s /usr/bin/git/bin/git /usr/local/bin/git

git使用记录

最近在写一些代码的时候,发现在公司和住的地方,同步很不方便,老是用U盘很麻烦,于是就想使用下git,于是开始看看git怎么用,遇到的一些问题,记录下
1.安装git,百度一下就可以了
2.配置下用户信息

$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com

3.初始化仓库,在某个目录下,初始化之后就可以用git管理目录下的文件了

$ git init
Initialized empty Git repository in f:/GitTest/.git/

4.新加文件并提交到版本库

$ echo "hahahah" > test.txt

$ git add test.txt

$ git commit -a -m "1"

5.删除文件

$ git rm test.txt
rm 'test.txt'

$ git commit -a -m "2 rm"
[master 47e19d1] 2 rm
 1 file changed, 1 deletion(-)
 delete mode 100644 test.txt

6.远程服务器,丢弃本地所有修改,完全和远程一样(本地和远程的不一样导致的错误,例如下面,这个本地的版本库我在添加远程之前,是有做过一些操作的,然后把远程pull到本地的时候,就报错了,如果本地的东西可以放弃掉不要的话,可以使用下面的策略)

$ git remote add origin git@github.com:scchary/Test1.git

$ git pull origin
warning: no common commits
remote: Counting objects: 81, done.
remote: Compressing objects: 100% (44/44), done.
remote: Total 81 (delta 7), reused 79 (delta 5), pack-reused 0
Unpacking objects: 100% (81/81), done.
From github.com:scchary/Test1
 * [new branch]      master     -> origin/master
You asked to pull from the remote 'origin', but did not specify
a branch. Because this is not the default configured remote
for your current branch, you must specify a branch on the command line.

$ git fetch origin

$ git reset --hard origin/master

7.本地版本回溯之后再push到远程的时候报错,

$ echo "test" >> t3.txt

$ git add t3.txt

$ git commit -a -m "test add file"
[master 4428651] test add file
warning: LF will be replaced by CRLF in t3.txt.
The file will have its original line endings in your working directory.
 1 file changed, 1 insertion(+)
 create mode 100644 t3.txt

$ git push origin master   #新创建了一个文件,并提交push到远程,这是远程就是在新的版本库了
Counting objects: 4, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 263 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To git@github.com:scchary/Test1.git
   b3677f6..4428651  master -> master

$ git reflog
4428651 HEAD@{0}: commit: test add file
b3677f6 HEAD@{1}: commit: test
2620363 HEAD@{2}: reset: moving to origin/master
47e19d1 HEAD@{3}: commit: 2 rm
821154b HEAD@{4}: commit (initial): 1

$ git reset --hard b3677f6 #版本回溯
HEAD is now at b3677f6 test

$ ls
t1.txt  t2.txt  test.txt  testA.txt  #添加的t3文件确实不见了


$ git push origin  master   #push到远程的时候报错,因为现在本地比远程的版本旧,所以要先pull
To git@github.com:scchary/Test1.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:scchary/Test1.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 push -f origin master
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:scchary/Test1.git
 + 4428651...b3677f6 master -> master (forced update)

8.忽略掉已经添加版本库的文件,git可以在.gitignore文件里面设置忽略的文件,比如

$ cat .gitignore
test.txt

上面就把test.txt文件夹忽略掉了,之后这个文件的更改git是不会管的,但是这个如果在设置.gitignore之前,test.txt就已经加入到了git,那么这个设置是无效的,可以利用这个命令来设置,

jin@JIN /f/GitTest (master)
$ git rm --cached test.txt