from:http://beta.segmentfault.com/q/1010000002564327

作为 Repo 的维护者,最常见的事情就是从某一 ref 开始到 HEAD保留下来,然后之前的历史删除。因为这个任务比较常见,所以这里也有一个 shell script 分享给你:

#!/bin/bash git checkout --orphan temp $1 git commit -m "截取的历史记录起点" git rebase --onto temp $1 master git branch -D temp 

使用的时候这样(比如该脚本保存叫 git-detach): git-detach <ref>,其中 <ref> 就是你要保留的历史记录的起点。

需要注意的是,这个脚本只是把历史记录“分离”开来,然后其中的一部分没有了可见的引用因此在历史记录里看不见,然而它们的 git object 仍然存在(换言之你还能恢复过来,自行查阅 git-reflog),如果你真要彻底丢掉这些历史(为了给 repo 减肥),可以用 git gc --prune,那就再也找不回来了。

P.S. 这个脚本依赖 Orphan Branch,低版本的 Git 不支持(大概是 < v1.7.x),有替代方案自己 Google 吧

$ git filter-branch --tree-filter 'rm -f testme.txt' HEAD
Rewrite bb383961a2d13e12d92be5f5e5d37491a90dee66 (2/2)
Ref 'refs/heads/master'
 was rewritten
$ git ls-remote .
230b8d53e2a6d5669165eed55579b64dccd78d11        HEAD
230b8d53e2a6d5669165eed55579b64dccd78d11        refs/heads/master
bb383961a2d13e12d92be5f5e5d37491a90dee66        refs/original/refs/heads/master
$ git update-ref -d refs/original/refs/heads/master [bb383961a2d13e12d92be5f5e5d37491a90dee66]
$ git ls-remote .
230b8d53e2a6d5669165eed55579b64dccd78d11        HEAD
230b8d53e2a6d5669165eed55579b64dccd78d11        refs/heads/master
$ rm -rf .git/logs
$ git reflog --all
$ git prune
$ git gc
$ du -hs
 84K    .

posted @ 2015-03-26 18:32 小马歌 阅读(848) | 评论 (0)编辑 收藏
 
跟踪取消:                                $ git rm --cached x.txt
 
跟踪取消的含义是,把文件从git中拿出来,不再进行版本跟踪,但保留工作区的文件。操作前,如果:
 
 
       1)该文件处于已提交状态,则此操作把该文件置成“未跟踪”状态,同时,隐性的执行了该文件的需要提交删除操作。再执行 git commit -m "...", 该文件彻底从 repository 中删除。       此命令能执行是因为“已暂存”与“已提交”一致。
 
       2)该文件处于“已提交”状态之后的“已修改”。则此操作把该文件置成“未跟踪”状态,同时,隐性的执行了该文件的需要提交删除操作。再执行 git commit -m "...", 该文件彻底从 repository 中删除。而且,已经修改的文件保留,不会丢失。此命令能执行是因为“已暂存”与“已提交”一致。
 
       3)该文件处于“已暂存”状态之后未修改。则此操作把该文件置成“未跟踪”状态,同时,隐性的执行了该文件的需要提交删除操作。再执行 git commit -m "...", 该文件彻底从 repository 中删除。此命令能执行是因为“已提交”与“已修改”一致。
 
 
       4)该文件处于“已暂存”状态之后的“已修改”。         此命令不能执行,因为“已暂存”既与“已提交”不一致,也与“已修改”不一致,造成信息丢失的风险,因此,对用户进行风险提示。如果强行删除,则需要加 -f , 即, git rm -f --cached a.txt。 结果是, 把该文件置成“未跟踪”状态,同时,隐性的执行了该文件的需要提交删除操作。再执行 git commit -m "...", 该文件彻底从 repository 中删除。此命令丢失原“已暂存”信息。
 
 
      注意:git rm -f --cached a.txt  与 git rm -f a.txt 之间的区别: 前者保留工作区的文件,后者是全部删除。
 
补充提交:                                $ git commit --amend
说明: 如果上次提交之后没有Stage新的文件,则这次补充提交只更新提交说明。
       如果有重新stage的文件,则这次提交把该文件加入到上次提交,即,本次补充和上次提交合并成一个。
暂存取消:                                $ git reset HEAD benchmarks.rb
注意:如果一个文件已经暂存了一个版本,后来又暂存了一个更新的版本,然后用git reset HEAD 取消后暂存的版本,则第一次暂存的本版不会恢复。
修改取消:                                $ git checkout -- benchmarks.rb
注意:如果已暂存之后没提交,进行了修改,这个修改取消,使用已暂存来覆盖,而不是已提交的;如果该已暂存已提交,则使用已提交覆盖。也就是说,要想彻底的用已提交的版本覆盖本地修改,则要查看该文件是否有已暂存,如果有,要用上一个命令先把它清除。
注意:修改取消后,无法恢复。
总之,只要提交的东西,总能想法设法找回来,但没提交的东西,一旦被覆盖,就有可能永久丢失。
[远程操作]
显示配置了哪些远程服务器:                      $ git remote                                     
显示配置了哪些远程服务器,同时显示URL:         $ git remote -v             
显示远程 详细信息:                             $ git remote show origin
修改远程标识名字:                              $ git remote rename pb paul
删除远程配置:                                  $ git remote rm paul
增加一个远程配置:                   $ git remote add pb git://github.com/paulboone/ticgit.git 
获取:                              $ git fetch pb
或者:                               $ git fetch origin
注意:
1)该分支可以用 pb/master 访问
2)获取到本地之后,并未自动merge,也未改变本地任何东西。
推送:                               $ git push origin master
注意,推送的条件:
1)从该远程克隆;
2)有写权限;
3)从上次克隆(或推送)至今没有更新,如果有更新,则你要先 fetch 然后再push。
标签操作:
查看所有标签:                               $ git tag
注意:标签显示的顺序无太多含义。
查看特定标签:                               $ git tag -l 'v1.4.2.*'
打新标签:                                   $ git tag -a v1.4 -m 'my version 1.4'
显示某个标签:                               $ git show v1.4
签署标签:                                   $ git tag -s v1.5 -m 'my signed 1.5 tag'
轻量级标签:                                 $ git tag v1.6
验证标签:                                   $ git tag -v v1.4.2.1
后期加注标签:                               $ git log --pretty=oneline
                                             $ git tag -a v1.2 9fceb02
分享(推送)标签:                           $ git push origin v1.5
分享(推送)所有标签:                       $ git push origin --tags
posted @ 2015-03-26 09:50 小马歌 阅读(274) | 评论 (0)编辑 收藏
 
【简介】 
版本控制系统(VCS, Version Control System) 可以分为集中式(CVCS, Centralized Version Control System, 如 CVS, Subversion)和分布式(DVCS, Distributed Version Control System,如 Git 等)版本控制系统。
传统的集中式版本控制系统,本地只保存代码库的一个版本拷贝。 所有历史版本都保存在服务器。GIT 与之最大的不同是,本地不仅保存一个快照,而且保存着整个代码库(repository)。因此它可以“离线”工作。 
在 Window 上安装: http://code.google.com/p/msysgit
GIT 起源于 LINUX 开发。Linux 开发早期(1992-2002)没有使用版本控制工具,直到 2002 年开始使用一个非开源的工具 BitKeeper。一开始这个工具还给 Linux 免费使用,后来想收费了,充满自由精神 Linux 成员们肯定不会屈服于这个要挟,一怒之下开发了一个自由的版本控制工具。2005 年,GIT 诞生 。
 
参考:官网:http://git-scm.com/
     手册:http://www.kernel.org/pub/software/scm/git/docs/
     参考:http://gitref.org/
     ProGit: http://progit.org/book/
【GIT 基础】
 
GIT 使用 SHA-1 哈希码(40个字符)来标识提交,同时保证本次提交后整体(一个快照)的完整性。 
文件状态:
文件状态分为:未跟踪 (untracked) 和已跟踪 (tracked),已跟踪又分为三种状态: 已暂存(staged),已修改(modified),已提交(committed)
一般过程如下:
1) 新建文件,该文件状态为“未跟踪”,位于工作区;
2) 用 git add a.txt  加入该文件,状态变为已跟踪的“已暂存”,位于暂存区;
3) 用 git commit a.txt -m "ha"  提交该文件,状态变为“已提交”,位于代码库(repository )
或者,如果存在修改的情况,增加如下2.1和2.2两个步骤:
 
1) 新建文件,该文件状态为“未跟踪”,位于工作区;
2) 用 git add a.txt  加入该文件,状态变为已跟踪的“已暂存”,位于暂存区;
2.1)编辑该文件并保存,状态变为“已修改”,位于工作区。(注意,位于暂存区的文件独立存在!)
2.2) 用 git add a.txt  加入该文件,状态变为“已暂存”,位于暂存区。(注意,原暂存区的文件被覆盖!)
3) 用 git commit a.txt -m "ha"  提交该文件,状态变为“已提交”,位于代码库(repository )
考虑更广泛的情况,状态迁移图如下所示: 
Git <wbr>使用 <wbr>- <wbr>1. <wbr>文件操作和历史查看
注意:用 git status 查看目前所有文件的状态。
GIT 配置:
三种配置范围类型:
1)所有用户 --system,   存在 /etc/gitconfig 文件中。(对windows来说,是 msysgit 的安装目录)
2)本用户 --global,    存在 ~/.gitconfig  文件中。(对windows 来说,是 C:\Documents and Settings\$USER)
3)本项目               存在 .git/config 文件中。
注意:后面的重载前面的。例如:用--global设置,可以在所有项目中使用这个设置;如果有一个项目你想使用一个特别的设置,就可以使用不带参数的 git config 重新设置,则它只作用于这个项目。如果用 git config --list 查看这些设置,可能会列出多个,但最后那个起作用。
用户信息
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
文本编辑器
$ git config --global core.editor emacs
查看配置信息
$ git config --list
或者只看一个信息:
$ git config <key>
【常用操作】 
(GIT 1.7.4 on  Windows)
获取帮助:                       $ git help <verb>
初始化仓库:                     $ git init
(说明: 如果该目录有文件,则都会处于“未跟踪”状态的。)
克隆仓库:                       $ git clone git://github.com/schacon/grit.git
克隆仓库,并换个名字:           $ git clone git://github.com/schacon/grit.git mygrit
跟踪一个新文件:                 $ git add readme.txt
说明: 
1) 跟踪之后,该文件状态是“已暂存”的。 (Changes to be committed:)
2)修改一个已暂存的文件,该文件会出现在两个记录区中。
3) 如果跟踪错了,想把他删除(不删除工作区的),则用 git rm --cached readme.txt。状态变成“未跟踪”,如果该文件已经修改了,则加  -f 参数强行删除暂存区的文件(已修改的文件不被覆盖)。
跟踪一组新文件:                 $ git add *.txt
跟踪一个目录中的所有文件:       $ git add mydir
说明:如果该目录下有子目录,则进行递归操作。
修改之后,暂存一个文件:                           $ git add readme.txt
说明:取消已暂存的文件(已暂存到已修改):         $ git reset HEAD readme.txt
忽略某些文件:                   在.gitignore 文件中加入下面两行:    *.[oa]    *~
*.a       # 忽略所有 .a 结尾的文件
!lib.a    # 但 lib.a 除外
/TODO     # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
build/    # 忽略 build/ 目录下的所有文件
doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
注意:.gitignore 文件放在工程的根目录即可,但是要把它用 git add 加入跟踪或者提交。
 
比较:
查看尚未暂存的更新:                   $ git diff
说明:比较“已修改”和“已暂存(或已提交)”。
查看尚未提交的更新:                    $ git diff --cached
      或                               $ git diff --staged
说明:比较“已暂存”和已提交。 
 
提交:
提交更新(只更新暂存中的):           $ git commit
提交更新(只更新暂存中的):           $ git commit -m "task12, added implementation for usr mrg."
直接提交更新(更新暂存中的和已修改的): $ git commit -a -m "task12, added implementation forg."
从文件中取注释:                       $ git commit --file notefile
 
重新获取:
抛弃已修改,用已提交覆盖               $ git checkout A.java
说明:此命令对已暂存文件没作用。 
 
删除文件:
从工作区可以直接删除文件,这是运行 git status, 显示:
 
  Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
      deleted:    a
可以用 git rm 删除 a。注意:如果 a 是已提交的文件,则还需要运行 git commit 以确保在代码库中删除。如果该文件尚未提交,则无需运行git commit。 
也可以直接使用 git rm 删除文件,但如何文件处于“已修改” 则需要加 -f
移除已跟踪文件,恢复到“未跟踪”       $ git rm --cached A.java
说明:如果文件已修改,则需 -f ,并且不覆盖修改过的内容。 
强行移除修改后文件(从暂存区和工作区中删除):      $ git rm -f a.a 
移除目录下的所有文件(递归):                    $ git rm log/\*.log
移除目录下的所有文件(无递归):                  $ git rm log/*.log
 
改名(只改工作区和暂存区):                      $ git mv file1 file2
相当于:                                          $ mv README.txt README
                                                  $ git rm README.txt
                                                  $ git add README
历史查看 :
查看提交历史(全部):                             $ git log
查看提交历史,并显示统计信息:                    $ git log --stat
查看提交历史并查看差异:                          $ git log -p
查看最近2次提交历史并查看差异:                   $ git log -p -2
查看最近2周内提交历史:                           $ git log --since=2.weeks
查看某个时刻之后的提交历史:                      $ git log --since="2008-09-14"
查看某个时刻以前的提交历史:                      $ git log --until="2008-09-14"
查看某个作者的提交历史:                          $ git log --author="stupid"
其他:
-(n) 仅显示最近的 n 条提交
--since, --after 仅显示指定时间之后的提交。
--until, --before 仅显示指定时间之前的提交。
--author 仅显示指定作者相关的提交。
--committer 仅显示指定提交者相关的提交。
例如:
$ git log --pretty="%h:%s" --author=gitster --since="2008-10-01" \
   --before="2008-11-01" --no-merges -- t/
 
查看提交历史,并单行显示:                        $ git log --pretty=oneline
查看提交历史,并格式化显示:                      $ git log --pretty=format:"%h - %an, %ar : %s"
例如:
$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 11 months ago : changed the version number
085bb3b - Scott Chacon, 11 months ago : removed unnecessary test code
a11bef0 - Scott Chacon, 11 months ago : first commit
 
%H 提交对象(commit)的完整哈希字串
%h 提交对象的简短哈希字串
%T 树对象(tree)的完整哈希字串
%t 树对象的简短哈希字串
%P 父对象(parent)的完整哈希字串
%p 父对象的简短哈希字串
%an 作者(author)的名字
� 作者的电子邮件地址
� 作者修订日期(可以用 -date= 选项定制格式)
%ar 作者修订日期,按多久以前的方式显示
%cn 提交者(committer)的名字
� 提交者的电子邮件地址
� 提交日期
%cr 提交日期,按多久以前的方式显示
%s 提交说明
 
查看提交历史,并图形化显示:               $ git log --pretty=format:"%h %s" --graph
例如:
$ git log --pretty=format:"%h %s" --graph
* 2d3acf9 ignore errors from SIGCHLD on trap
*  5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
|\
| * 420eac9 Added a method for getting the current branch.
* | 30e367c timeout code and tests
* | 5a09431 add timeout protection to grit
* | e1193f8 support for heads with slashes in them
|/
* d6016bc require time for xmlschema
*  11d191e Merge branch 'defunkt' into local
 
其它:
-p 按补丁格式显示每个更新之间的差异。
--stat 显示每次更新的文件修改统计信息。
--shortstat 只显示 --stat 中最后的行数修改添加移除统计。
--name-only 仅在提交信息后显示已修改的文件清单。
--name-status 显示新增、修改、删除的文件清单。
--abbrev-commit 仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。
--relative-date 使用较短的相对时间显示(比如,“2 weeks ago”)。
--graph 显示 ASCII 图形表示的分支合并历史。
--pretty 使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)。
 
最重要的是,如果你觉着上面这些查看历史的命令太难用,你可以使用图形化工具:gitk,一切都清晰了。
posted @ 2015-03-26 09:47 小马歌 阅读(418) | 评论 (0)编辑 收藏
 
[基本概念] 
GIT branch 的本质是一个提交链表的指针。创建一个新的branch,实质是创建了当时提交链表的一个新指针。该指针和原指针独立操作,各自叠加新的提交后,形成各自的分支链。
“在分支上”的含义,新建一个分支之后,建立此分支以前的提交也称为在这个分支上。
HEAD的含义:当前branch。 随着git branch checkout <branch> 改变。
分支不是线形性:如果发生过merge,则即使 HEAD 相同,链表也不具有唯一性。(即某些提交有多父情况)
 
为什么要及时删掉不用的分支:防止提交查看时显示过多的分支。
merge 时,如果自动merge没有冲突,则 GIT 产生一个新的提交。如果有 冲突,则GIT产生一个未提交。
实践中,可以有三个分支:
1, master
2, dev
3, Topic:针对某个具体问题,短期存在,需要经常的rebase。
问题:如果删除一个分支,那么它上面的未 merge 的提交会一起删除吗?
[基本操作]
查看分支:                                       $ git branch
创建分支:                                      $ git branch mybranch
切换分支:                                      $ git checkout mybranch
创建并切换分支:                                $ git checkout -b mybranch
合并分支:(merge from)                          $ git checkout master
                                                $ git merge mybranch   (merge from mybranch)
使用 merge工具(有冲突的情况下):              $ git mergetool
删除分支:                                      $ git branch -d mybranch
强制删除分支 (上面有尚未 merge 的提交):        $ git branch -D mybranch
列出所有分支:                                  $ git branch
查看各个分支最后一次提交:                      $ git branch -v
查看哪些分支合并入当前分支(可以删了):        $ git branch --merged
查看哪些分支未合并入当前分支:                  $ git branch --no-merged
远程: 
更新远程库到本地:                              $ git fetch origin
如果有新分支,则分支名:orgin/<branch>
 
取远程分支合并到本地分支:                      $ git merge origin/mybranch
用远程分支建一个本地分支:                      $ git checkout -b mybranch origin/mybranch
推送分支:                                      $ git push origin mybranch
 
推送分支,并换个名字:                          $ git push origin serverfix:awesomebranc
删除远程分支:                 $ git push origin  :mybranch
 
rebase:                                         $ git checkout mybranch
                                                $ git rebase master    (rebase from master)
 
举例:                                          $ git checkout server
                                                $ git rebase --onto master server client
                                                $ git checkout master
                                                $ git merge client  (fostforward)
                                                $ git rebase master server  (checkout sever)
                                                $ git merge server
                                                $ git branch -d client
                                                $ git branch -d server
 
merge 和 rebase 的区别:
1),从文件结果看,merge 和 rebase 可以达到同样效果。 
2),从历史纪录看,他们存在差异:merge 显示合并后的多父结点,呈现环形, 而 rebase 呈现线性结果,即它对分支历史进行合并操作。rebase 提供更好的历史呈现方式(似分支从未曾发生过),但有风险。 掌握一条原则:Do not rebase commits that you have pushed to a public repository. 即,不要对你提交过的分支进行 rebase。因为本地的改变会造成远端的困惑。 
3), 在实践中,可以尽量用 merge,慎用 rebase。
posted @ 2015-03-26 09:26 小马歌 阅读(232) | 评论 (0)编辑 收藏
 

标签可以针对某一时间点的版本做标记,常用于版本发布。

  • 列出标签

$ git tag # 在控制台打印出当前仓库的所有标签
$ git tag -l ‘v0.1.*’ # 搜索符合模式的标签

  • 打标签

git标签分为两种类型:轻量标签和附注标签。轻量标签是指向提交对象的引用,附注标签则是仓库中的一个独立对象。建议使用附注标签。
# 创建轻量标签
$ git tag v0.1.2-light

# 创建附注标签
$ git tag -a v0.1.2 -m “0.1.2版本”

创建轻量标签不需要传递参数,直接指定标签名称即可。
创建附注标签时,参数a即annotated的缩写,指定标签类型,后附标签名。参数m指定标签说明,说明信息会保存在标签对象中。

  • 切换到标签

与切换分支命令相同,用git checkout [tagname]
查看标签信息
git show命令可以查看标签的版本信息:
$ git show v0.1.2

  • 删除标签

误打或需要修改标签时,需要先将标签删除,再打新标签。
$ git tag -d v0.1.2 # 删除标签

参数d即delete的缩写,意为删除其后指定的标签。

  • 给指定的commit打标签

打标签不必要在head之上,也可在之前的版本上打,这需要你知道某个提交对象的校验和(通过git log获取)。
# 补打标签
$ git tag -a v0.1.1 9fbc3d0

  • 标签发布

通常的git push不会将标签对象提交到git服务器,我们需要进行显式的操作:
$ git push origin v0.1.2 # 将v0.1.2标签提交到git服务器
$ git push origin –tags # 将本地所有标签一次性提交到git服务器

 

注意:如果想看之前某个标签状态下的文件,可以这样操作

1.git tag   查看当前分支下的标签

2.git  checkout v0.21   此时会指向打v0.21标签时的代码状态,(但现在处于一个空的分支上)

3. cat  test.txt   查看某个文件


refer to:http://www.csser.com/dev/580.html

posted @ 2015-03-20 11:41 小马歌 阅读(240) | 评论 (0)编辑 收藏
 

转:http://beginor.github.io/2013/03/12/migrate-from-svn-to-git.html

准备工作

确认所有用户的本地修改都签入到服务器, 将 SVN 源代码的分支尽可能的合并到主干, 已经发布的做好归档信息, 并备份 SVN 库。 虽然迁移到 Git 的风险不大, 但是备份一下总是好的。

安装 Git , 这看起来是废话, 不装 Git 怎么迁移?

将用户映射到 Git

创建一个用户映射文件, 将 SVN 用户映射到 Git 用户, 这样可以保留用户的签入历史信息, 比如用户输入的修改记录等, 这个文件看起来是这样子的:

svnuser1 = gituser1 <gituser1@yourcompany.com> svnuser2 = gituser2 <gituser2@yourcompany.com> 

这样, 用户 svnuser1 签入的历史信息在迁移之后就会映射成 gituser1 , svnuser2 映射程 gituser2 。

编辑好用户映射文件之后, 保存为 users.txt 。

克隆 SVN 库

假设 svn 库的布局是标准的 trunk 、 branches 以及 tags , 运行下面的命令开始克隆 svn 库:

git svn clone <svn repo url> --no-metadata -A users.txt -t tags -b branches -T trunk <destination dir name> 

Git 会克隆 svn 完整的历史记录, 可能会需要很长的时间, 视 svn 库的历史而定。

转换分支及归档

克隆完成之后, 所有的 svn 归档在 git 看来都是远程分支 (remote tags) , 不是真正的 git 归档, 需要将他们手工转换为 git 归档, 然后再删除远程分支, 对于每一个分支或归档, 做如下操作(以 v1.0.1 归档为例):

git tag v1.0.1 tags/v1.0.1 git branch -r -d tags/v1.0.1 

所有的归档信息处理完成之后, git 本地库就有了完整的历史记录。

提交到 Git 库

现在可以放心的将代码提交到自己的 git 服务器了, 命令如下:

git remote add origin git@github.com:userid/project.git git push origin master --tags 

总的来说, 从 svn 迁移到 git 还是很容易的。

posted @ 2015-03-20 10:57 小马歌 阅读(289) | 评论 (0)编辑 收藏
 

Git如何进行分支管理?
     1、创建分支
     创建分支很简单:git branch <分支名>
     2、切换分支
     git checkout <分支名>
     该语句和上一个语句可以和起来用一个语句表示:git checkout -b <分支名>
     3、分支合并
     比如,如果要将开发中的分支(develop),合并到稳定分支(master),
     首先切换的master分支:git checkout master。
     然后执行合并操作:git merge develop。
     如果有冲突,会提示你,调用git status查看冲突文件。
     解决冲突,然后调用git add或git rm将解决后的文件暂存。
     所有冲突解决后,git commit 提交更改。
     4、分支衍合
     分支衍合和分支合并的差别在于,分支衍合不会保留合并的日志,不留痕迹,而 分支合并则会保留合并的日志。
     要将开发中的分支(develop),衍合到稳定分支(master)。
     首先切换的master分支:git checkout master。
     然后执行衍和操作:git rebase develop。
     如果有冲突,会提示你,调用git status查看冲突文件。
     解决冲突,然后调用git add或git rm将解决后的文件暂存。
     所有冲突解决后,git rebase --continue 提交更改。
     5、删除分支
     执行git branch -d <分支名>
     如果该分支没有合并到主分支会报错,可以用以下命令强制删除git branch -D <分支名>

http://winuxxan.blog.51cto.com/2779763/508955

posted @ 2015-03-20 10:57 小马歌 阅读(203) | 评论 (0)编辑 收藏
 

from:http://longgeek.com/2013/12/26/ci-system-structures-ii-gitlab-installation/#i-3

2013-12-26日 | 标签:    | 作者:

PDF24 Creator    Send article as PDF     

上一篇文章 CI 系统搭建:一. 基础环境设置、规划 大概规划了下环境,本文主要用来记录安装 Gitlab 的过程,主要参考官方文档 并没有做太多的修改。

设置源

设置国内 163 apt 源

# vim /etc/apt/sources.list deb http://mirrors.163.com/ubuntu/ precise main universe restricted multiverse deb http://mirrors.163.com/ubuntu/ precise-security universe main multiverse restricted deb http://mirrors.163.com/ubuntu/ precise-updates universe main multiverse restricted deb http://mirrors.163.com/ubuntu/ precise-proposed universe main multiverse restricted deb http://mirrors.163.com/ubuntu/ precise-backports universe main multiverse restricted  deb-src http://mirrors.163.com/ubuntu/ precise main universe restricted multiverse deb-src http://mirrors.163.com/ubuntu/ precise-security universe main multiverse restricted deb-src http://mirrors.163.com/ubuntu/ precise-proposed universe main multiverse restricted deb-src http://mirrors.163.com/ubuntu/ precise-backports universe main multiverse restricted deb-src http://mirrors.163.com/ubuntu/ precise-updates universe main multiverse restricted # apt-get update 

安装依赖包

Gitlab 依赖包、库

sudo apt-get install -y build-essential zlib1g-dev libyaml-dev libssl-dev libgdbm-dev libreadline-dev \                         libncurses5-dev libffi-dev curl openssh-server redis-server checkinstall \                         libxml2-dev libxslt-dev libcurl4-openssl-dev libicu-dev logrotate 

安装 markdown 文档风格依赖包

sudo apt-get install -y python-docutils  

安装 git,Gerrit 依赖 gitweb,同时 GitLab 依赖 git 版本 >= 1.7.10,Ubuntu apt-get 默认安装的是 1.7.9.5,当然不升级也是没有问题的

sudo apt-get install -y git git-core gitweb git-review 

升级 Git 版本(可选)

sudo apt-get install -y git gitweb sudo apt-get remove git-core sudo apt-get install -y libcurl4-openssl-dev libexpat1-dev gettext libz-dev libssl-dev build-essential cd /tmp curl --progress https://git-core.googlecode.com/files/git-1.8.4.1.tar.gz | tar xz cd git-1.8.4.1/ make prefix=/usr/local all sudo make prefix=/usr/local install # * 如果升级了 git 的版本,相应修改 Gitlab.yml 中的 git 脚本位置,这一步在 clone gitlab 后在操作* sudo -u git -H vim /home/git/gitlab/config/gitlab.yml bin_path: /usr/local/bin/git 

Gitlab 需要收发邮件,安装邮件服务器

sudo apt-get install -y postfix 

如果安装了 ruby1.8,卸载掉,Gitlab 依赖 2.0 以上

sudo apt-get remove ruby1.8 

下载编译 ruby2.0

mkdir /tmp/ruby && cd /tmp/ruby curl --progress ftp://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p353.tar.gz | tar xz cd ruby-2.0.0-p353 ./configure --disable-install-rdoc make sudo make install 

修改 gem 源指向 taobao

gem source -r https://rubygems.org/ gem source -a http://ruby.taobao.org/ 

安装 Bundel 命令

sudo gem install bundler --no-ri --no-rdoc 

系统用户

给 Gitlab 创建一个 git 用户

sudo adduser --disabled-login --gecos 'GitLab' git 

GitLab Shell

下载 Gitlab Shell,用来 ssh 访问仓库的管理软件

cd /home/git sudo -u git -H git clone https://github.com/gitlabhq/gitlab-shell.git cd gitlab-shell sudo -u git -H cp config.yml.example config.yml 

修改 gitlab-shell/config.yml

sudo -u git -H vim /home/git/gitlab-shell/config.yml gitlab_url: "http://gitlab.thstack.com/" 

安装 GitLab Shell

cd /home/git/gitlab-shell sudo -u git -H ./bin/install 

Mysql

安装 Mysql 包

sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev 

给 Gitlab 创建 Mysql 数据库并授权用户访问

sudo mysql -uroot -p > create database gitlabdb; > grant all on gitlabdb.* to 'gitlabuser'@'localhost' identified by 'gitlabpass'; 

GitLab

下载 GitLab 源代码,并切换到最新的分支上

cd /home/git sudo -u git -H git clone https://github.com/gitlabhq/gitlabhq.git gitlab cd gitlab sudo -u git -H git checkout 6-4-stable 

配置 GitLab,修改 gitlab.yml,其中 host: 项和 gitlab-shell 中 gitlab_url 的主机一致

cd /home/git/gitlab sudo -u git -H cp config/gitlab.yml.example config/gitlab.yml sudo -u git -H vim config/gitlab.yml host: gitlab.thstack.com email_from: gitlab@thstack.com support_mail: gitlab@thstack.com signup_enabled: true             #开启用户注册 

创建相关目录

cd /home/git/gitlab sudo -u git -H mkdir tmp/pids/ sudo -u git -H mkdir tmp/sockets/ sudo -u git -H mkdir public/uploads  sudo -u git -H mkdir /home/git/repositories sudo -u git -H mkdir /home/git/gitlab-satellites 

修改相关目录权限

sudo chown -R git:git log/ tmp/ sudo chmod -R u+rwX  log/ tmp/ public/uploads 

修改 unicorn.rb 监听端口为:8081

cd /home/git/gitlab/ sudo -u git -H cp config/initializers/rack_attack.rb.example config/initializers/rack_attack.rb sudo -u git -H cp config/unicorn.rb.example config/unicorn.rb sudo -u git -H vim config/unicorn.rb listen "gitlab.thstack.com:8081", :tcp_nopush => true 

配置 GitLab 访问 mysql 数据库设置

cd /home/git/gitlab/ sudo -u git cp config/database.yml.mysql config/database.yml sudo -u git -H vim config/database.yml   *修改 Production 部分:* production:   adapter: mysql2   encoding: utf8   reconnect: false   database: gitlabdb   pool: 10   username: gitlabuser   password: "gitlabpass"   host: localhost   socket: /var/run/mysqld/mysqld.sock 

设置 GitLab 使用指定邮箱发送邮件,注意 production.rb 的文件格式,开头空两格

cd /home/git/gitlab/ sudo -u git -H vim config/environments/production.rb   #修改 :sendmail 为 :smtp   config.action_mailer.delivery_method = :smtp   config.action_mailer.smtp_settings = {     :address              => "smtp.googlemail.com",     :port                 => 587,     :domain               => 'thstack.com',     :user_name            => 'gitlab@thstack.com',     :password             => 'password',     :authentication       =>  :plain,     :enable_starttls_auto => true   } end          # 上面内容加入到 end 里面 

安装 gem

修改 Gemfile 文件中源指向为 taobao

cd /home/git/gitlab/ sudo -u git -H vim Gemfile source "http://ruby.taobao.org/" 

虽然在文件中指向了国内 taobao 源,但是依然会卡一会,耐心等待…

cd /home/git/gitlab/ sudo -u git -H bundle install --deployment --without development test postgres aws 

初始化数据库并激活高级功能

cd /home/git/gitlab/ sudo -u git -H bundle exec rake gitlab:setup RAILS_ENV=production 

输入 yes 来初始化数据库、创建相关表,最后会输出 GitLab Web 管理员用来登录的账号和密码

Do you want to continue (yes/no)? yes ... Administrator account created: login.........admin@local.host password......5iveL!fe 

设置 GitLab 启动服务

cd /home/git/gitlab/ sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab sudo update-rc.d gitlab defaults 21 

设置 GitLab 使用 Logrotate 备份 Log

cd /home/git/gitlab/ sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab 

检查GitLab及其环境的配置是否正确:

cd /home/git/gitlab/ sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production System information System:         Ubuntu 12.04 Current User:   git Using RVM:      no Ruby Version:   2.0.0p353 Gem Version:    2.0.14 Bundler Version:1.3.5 Rake Version:   10.1.0  GitLab information Version:        6.4.2 Revision:       214a013 Directory:      /home/git/gitlab DB Adapter:     mysql2 URL:            http://gitlab.thstack.com HTTP Clone URL: http://gitlab.thstack.com/some-project.git SSH Clone URL:  git@gitlab.thstack.com:some-project.git Using LDAP:     no Using Omniauth: no  GitLab Shell Version:        1.8.0 Repositories:   /home/git/repositories/ Hooks:          /home/git/gitlab-shell/hooks/ Git:            /usr/bin/git 

启动 GitLab 服务

/etc/init.d/gitlab restart Shutting down both Unicorn and Sidekiq. GitLab is not running. Starting both the GitLab Unicorn and Sidekiq.. The GitLab Unicorn web server with pid 17771 is running. The GitLab Sidekiq job dispatcher with pid 17778 is running. GitLab and all its components are up and running 

最后编译一下

sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production 

Nginx

安装 Nginx 包

sudo apt-get install -y nginx 

配置 Nginx

cd /home/git/gitlab sudo cp lib/support/nginx/gitlab /etc/nginx/sites-available/gitlab sudo ln -s /etc/nginx/sites-available/gitlab /etc/nginx/sites-enabled/gitlab sudo vim /etc/nginx/sites-available/gitlab listen *:80 default_server; server_name gitlab.thstack.com; proxy_pass http://gitlab.thstack.com:8081; 

启动 Nginx

/etc/init.d/apache2 stop /etc/init.d/nginx restart 

访问

用浏览器访问: http://gitlab.thstack.com 用户名:admin@local.host 密码:5iveL!fe 

2: https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/insta llation.md

界面简单使用

使用 admin@local.host 账号登录: gitlab-login

登录后系统让修改密码,先修改密码: gitlab-set_pass

修改完密码后,用新密码登录一下,然后修改 Admin 用户得邮箱地址为:admin@thstack.com gitlab-set-email

点击保存更改后,系统会自动给刚才输入的邮箱地址发送一封确认修改信息,点击邮件内容中的连接后会自动用新账号邮箱登录。

创建一个 GROUP:

gitlab-click-group

输入 Group 名字为:DevGroup gitlab-create-gourp

点击创建项目: gitlab-click-project

创建一个项目,名为:OpenStack,这个项目属于 DevGroup: gitlab-create-project

创建完项目后,点击添加 ssh 密钥: gitlab-click-sshkey

生成 admin@thstack.com 邮箱密钥: gitlab-gen-sshkey

在界面输入刚才生成得密钥: gitlab-add-sshkey

再注册一个账号,登录页面点击注册按钮: gitlab-click-user

注册一个 Longgeek 用户,输入邮箱、密码,然后去输入得邮箱验证: gitlab-create-user

创建一个 Longgeek 用户,并生成密钥: gitlab-longgeek-gen-sshkey

用 longgeek@thstack.com 用户登录 GitLab,添加刚才生成得密钥到 sshkey 里: gitlab-longgeek-add-sshkey

用 admin@thstack.com 用户登录 GitLab,把 longgeek@thstack.com 添加到 DevGroup 组中,权限是 Reporter,这样 longgeek 用户也可以访问 OpenStack 这个项目,不过没有权限直接 Push: gitlab-add-longgeek-gourp

用 longgeek@thstack.com 用户登录就可以看到 OpenStack 项目: gitlab-longgeek-view-project

用 longgeek@thstack.com clone 项目,尝试 push: gitlab-longgeek-try-push

很显然 longgeek 用户是没有 push 到 master 分支得权限。接下来会安装 Gerrit、Jenkins。以及它们三个如何整合成流程。请参考后面得文章。

posted @ 2015-03-19 16:37 小马歌 阅读(413) | 评论 (0)编辑 收藏
 


Thrift在0.9.1版本之前,一直只提交了对单一接口服务的支持,即一个RPC服务器(对应一个端口)支持一个服务接口的实现。

但是很多时候,我们的服务不能实现在一个接口里,一是接口里的方法越来越多,不好管理和使用;二是根据职责的单一要求,不能类型的方法,不能放在同一接口里。

在 Thrift-0.9.1之前,我们要解决上面的问题,一是通过多个RPC服务器来实现,这个方法必然导致了我们RPC服务器越来越多,管理上麻烦;二是通过其他的一些途径,如使用netty作为RPC服务器等,这个方法实现上相对麻烦一些,需要去了解netty的知识。

这些方法在这里就不再详述了。

从Thrift-0.9.1开始,thrift开始提供对多接口服务的支持,使得我们开发多接口RPC服务相对简单多了。

这里还是给出例子来说明。

首先,我们做了两个接口定义文件来定义两个接口:

namespace javacom.eli.test.service

struct Topic

{

    1: i32 uid,

    2: string name,

    3: string content

}

service TopicService

{

    void store(1: Topic topic),

    Topic retrieve(1: i32 uid)

}

 

 

namespace javacom.eli.test.service

struct User

{

    1: i32 uid,

    2: string name,

    3: string blurb

}

service UserService

{

    void store1(1: User user),

    User retrieve1(1: i32 uid)

}

 

 

然后使用Thrift-0.9.1.exe生成相应的JavaBean及接口:

 

 

然后,我们写两个接口的实现类:

import org.apache.thrift.TException;

 

import com.eli.test.service.Topic;

import com.eli.test.service.TopicService;

 

public class TopicImpl implements TopicService.Iface{

public void store(Topic topic)throws TException

{

        System.out.println("theinput topic: ");

        System.out.println("id:"+topic.getUid());

        System.out.println("name:"+topic.getName());

        System.out.println("content:"+topic.getContent());

}

public Topic retrieve(int uid)throws TException

{

        System.out.println("theinput uid: "+uid);

        return newTopic(uid,"test","test");

}

 

}

 

 

 

import org.apache.thrift.TException;

 

import com.eli.test.service.User;

import com.eli.test.service.UserService;

 

public class UserImpl implements UserService.Iface{

 

public void store1(User user)throws TException

{

        System.out.println("theinput user: ");

        System.out.println("uid:"+user.getUid());

        System.out.println("name:"+user.getName());

        System.out.println("blur:"+user.getBlurb());

}

public User retrieve1(int uid)throws TException

{

        System.out.println("theinput uid: "+uid);

        return newUser(uid,"tom","123");

}

}

 

 

 

上述工作完成以后,就可以写服务器代码了。

服务器代码与单一接口的服务器代码最大的不同是使用了“TMultiplexedProcessor”类,通过该类,可以注册多个接口的服务实现类:

TMultiplexedProcessor processor = new TMultiplexedProcessor();

             

       processor.registerProcessor("TopicService"newTopicService.Processor<TopicService.Iface>(newTopicImpl()));

    processor.registerProcessor("UserService"new UserService.Processor<UserService.Iface>(new UserImpl()));

 

 

其他代码就跟以前的服务器代码一样了。

完整的服务器代码如下:

TMultiplexedProcessor processor = newTMultiplexedProcessor();

          

           TServerTransport t = new TServerSocket(9090);

           TServer server = new TThreadPoolServer(newTThreadPoolServer.Args(t).processor(processor));

          

           processor.registerProcessor("TopicService"newTopicService.Processor<TopicService.Iface>(newTopicImpl()));

           processor.registerProcessor("UserService"newUserService.Processor<UserService.Iface>(newUserImpl()));

          

//         TSimpleServer server = new TSimpleServer(new Args(t).processor(processor));

 

           System.out.println("the serveris started and is listening at 9090...");

          

        server.serve();

 

 

最后是客户端代码了,客户端代码的不同之处是引入了“TMultiplexedProtocol”类,它来帮助客户端区别调用哪个接口:

TMultiplexedProtocol mp1 = new TMultiplexedProtocol(protocol,"TopicService");

                           

    TopicService.Clientservice1 = new TopicService.Client(mp1);

 

完整的客户端测试代码如下:

              TSocket transport = new TSocket("localhost",9090);

             

              TBinaryProtocol protocol = new TBinaryProtocol(transport);

             

              TMultiplexedProtocolmp1 = new TMultiplexedProtocol(protocol,"TopicService");

             

              TopicService.Client service1 = newTopicService.Client(mp1);

             

              TMultiplexedProtocolmp2 = new TMultiplexedProtocol(protocol,"UserService");

             

              UserService.Client service2 = newUserService.Client(mp2);

             

              transport.open();

             

              service1.store(new Topic(668,"test topic","just a test!"));

             

              service2.store1(new User(888,"tom","haha"));

             

              System.out.println(service1.retrieve(168));

              System.out.println(service2.retrieve1(999));

             

           transport.close();

 

 

运行服务器代码和客户端代码,则客户端会打印如下结果:

Topic(uid:168, name:test, content:test)

User(uid:999, name:tom, blurb:123)

 

 

服务器端会打印如下的信息:

the server is started and is listening at 9090...

the input topic:

id: 668

name: test topic

content: just a test!

the input user:

uid: 888

name: tom

blur: haha

the input uid: 168

the input uid: 999

 

通过上面的例子,可以看到,Thrift-0.9.1版本很简单的解决了多接口服务的问题,随便说一下,该版本并没有解决所有语言的多接口实现问题,只是解决了Java和其他几个语言。请大家在使用的时候,查清楚您使用的语言是否解决了这个问题。

posted @ 2015-03-18 17:22 小马歌 阅读(433) | 评论 (0)编辑 收藏
 

一、开启nginx的监控

1)、nginx简单状态监控

在nginx.conf中添加如下代码即可监控nginx当前的状态,然后访问http://serverip/status即可访问

location /status {
stub_status on;
access_log off;
}

一般显示为

Active connections: 16 
server accepts handled requests
191226 191226 305915 
Reading: 0 Writing: 1 Waiting: 15

ctive connections: 对后端发起的活动连接数.

Server accepts handled requests: Nginx总共处理了24个连接,成功创建24次握手(证明中间没有失败的),总共处理了129个请求.

Reading: Nginx 读取到客户端的Header信息数.

Writing: Nginx 返回给客户端的Header信息数.

Waiting: 开启keep-alive的情况下,这个值等于 active – (reading + writing),意思就是Nginx已经处理完成,正在等候下一次请求指令的驻留连接.
注意的,本模块默认是不会编译进Nginx的,如果你要使用该模块,则要在编译安装Nginx时指定:
 ./configure –with-http_stub_status_module 
 查看已安装的 Nginx 是否包含 stub_status 模块
 #/usr/local/nginx/sbin/nginx -V 
 TLS SNI support disabled
configure arguments: --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-file-aio --with-http_ssl_module 
 
2)、nginx的图形化监控-nginx-RRD stats
 
nginx-rrdnginx官方推荐的一款Nginx监控工具,利用nginx-rrd可以很方便的生成图表,便于我们查看。

1、运行环境(centos):

在安装前需要安装好rrdtool这个画图工具和相应的perl模块,可以先运行:

yum install rrdtool libhtml-parser-perl libwww-perl librrds-perl librrd2-dev

确保rrdtool和相应的perl被安装上。

2、安装配置

下载:wget http://soft.vpser.net/status/nginx-rrd/nginx-rrd-0.1.4.tgz

解压:tar zxvf nginx-rrd-0.1.4.tgz

进入nginx-rrd目录,cd nginx-rrd-0.1.4/

复制主程序:cp usr/sbin/* /usr/sbin

复制配置文件cp etc/nginx-rrd.conf /etc

复制定时执行文件:cp etc/cron.d/nginx-rrd.cron /etc/cron.d

创建nginx-rrd生成目录:mkdir /home/wwwroot/nginx && mkdir /home/wwwroot/nginx/rrd

cp html/index.php /home/wwwroot/nginx

编辑/home/wwwroot/nginx/index.php修改登录密码

<?php
header("Content-Type: text/html; charset=utf-8");

$password = "admin"; 

.........

编辑配置文件nginx-rrd.conf,修改完成后如下:

#####################################################
#
# dir where rrd databases are stored
RRD_DIR="/home/wwwroot/nginx-rrd/";
# dir where png images are presented
WWW_DIR="/home/wwwroot/nginx/";
# process nice level
NICE_LEVEL="-19";
# bin dir
BIN_DIR="/usr/sbin";
# servers to test
# server_utl;server_name
SERVERS_URL="http://127.0.0.1/status;127.0.0.1"

多个server,可以SERVERS_URL中空格分开,前部分为nginx_status的地址,后面为被监控主机的域名。

SEVERS_URL 格式

注意,nginx.conf虚拟主机server{}中,需要已经加入:

location /status {
stub_status on;
access_log off;
}

以上设置就完成,可以自行运行一下:/usr/sbin/nginx-collect ,启动收集程序。cron会15分钟生成一次数据。

如果没有定时执行生成数据,可以在/etc/crontab最后面加上:

* * * * * root /usr/sbin/nginx-collect
*/15 * * * * root /usr/sbin/nginx-graph

然后输入然后访问http://serverip/nginx/即可访问。

 

二、开启tomcat的监控

1)、tomcat6的配置

修改tomcat/conftomcat-users.xml文件中</tomcat-users>节点之前添加如下代码即可。

 <user username="admin" password="admin" roles="manager"/>

然后输入然后访问http://serverip:8080/manager/status即可访问。

2)tomcat7的配置

修改tomcat/conftomcat-users.xml文件中</tomcat-users>节点之前添加如下代码即可。

<role rolename="manager-gui"/>
<user username="tomcat" admin="admin" roles="manager-gui"/>

然后输入然后访问http://serverip:8080/manager/status即可访问。

posted @ 2015-03-17 10:00 小马歌 阅读(2417) | 评论 (0)编辑 收藏
仅列出标题
共95页: First 上一页 11 12 13 14 15 16 17 18 19 下一页 Last