Git远端仓库版本回退方法

今天恰好有将GitHub中仓库版本回退的需求,按照之前本地git回退版本后再次push的方法出错,经过研究后找到了解决方法。

  • 首先git pull保证本地分支与远端分支版本同步
  • 先找到要退回的commit id:
git reflog
  • 接着本地回退版本:
git reset --hard [commit id]
  • 强制推送到远端仓库
git push -f origin master

这里特别要注意的是,本地分支回滚后,版本将落后远程分支,必须使用强制推送覆盖远程分支,否则无法推送到远程分支。

有关远端公共分支回滚版本

请参考原文:http://blog.csdn.net/fuchaosz/article/details/52170105

Centos7搭建Git及安装使用

一、Centos7.2 下 Git的安装

1、查看是否安装了git

rpm -qa|grep git

未分类

若已经安装,需要先卸载。卸载命令如下:

rpm -e --nodeps git  或者  rpm -e git

未分类

2、安装Git

yum install git

未分类

输入y,并回车

未分类

再使用 rpm -qa|grep git 来查看是否已经安装好了Git。

未分类

3、创建Git仓库

mkdir six_git        // 创建文件夹
useradd six             //创建用户名并设置密码
passwd six            //(系统会提示输入密码和再次密码)
groupadd git        // 创建组
git init --bare        //进入所创建的文件夹,初始化一个仓库
chown -R six:git /var/www/six_git/        // 赋权限

未分类

二、windows7 下连接Git版本库

1、安装Git 和 TortoiseGit(小乌龟)

2、在本地创建文件夹

>在windows7中某个盘符下创建一个名为“six” 的文件夹,这个文件夹就是我们与远程仓库通讯的文件夹。

3、进入“six”文件夹,右击菜单设置本机用户名和email

为了直观分辨不同用户为版本开发的贡献,需要设定用户名和email
下面分别是中文版和英文版的 TortoiseGit

未分类

未分类

未分类

未分类

4、Clone版本库(克隆)

在要克隆版本库的文件夹中点击右键,点击“Git克隆”菜单,根据图中信息填写后,点击确定,输入当时创建“six”账户是设置的密码即可。

未分类

未分类

未分类

输入创建“six”用户时,设置的密码。
英文版本:

未分类

未分类

填写好后,点击“ok”按钮,并要求输入密码。

未分类

5、添加文件

在clone库的文件夹中添加一个测试文件,并在空白处点击邮右键,选择“TortoiseGit”-à “添加”

未分类

勾选未受版本控制的文件,也就是刚刚创建的测试文件,点击确定按钮。

未分类

添加完成后,弹出“加入完成”对话框,点击确定即可

未分类

再在该文件夹空白出点击右键,点击“Git提交(C)->”master”…”

未分类

在对话框中填写相关的说明信息并选择文件,点击提交即可。

未分类

6、更新版本库

更新版本库前应该改先从服务器上“拉取”一下,再把自己修改的内容“推送”到服务器上.

未分类

未分类

三、建立发布版本库

1、在centos中建立发布版本库,然后进入文件夹。

未分类

2、更新版本库,进入版本目录,执行“git pull”命令

未分类

3、 禁止shell登陆

出于安全考虑,git用户不允许登录shell,这可以通过编辑/etc/passwd文件完成。
找到类似下面的一行:

six:x:502:502::/home/six:/bin/bash
改为
six:x:502:502::/home/six:/usr/local/git/bin/git-shell
或者
six:x:502:502::/home/six:/usr/bin/git-shell
six:x:502:502::/home/six:/bin/false

git用户可以正常通过ssh使用git,但无法登录shell,因为我们为git用户指定的git-shell每次一登录就自动退出。

未分类

四、错误

未分类

在 windows文件夹 下 bash命令中输入:

git fetch --all
git reset --hard origin/master

Git的bash操作:

进入git bash,我这个windows下个git已经安装配置完成了,所以直接clone,192.168.153.129为我centos7的ip
git clone [email protected]:/srv/git/project.git
输入git的密码
进入project.git
cd project.git
创建一个测试文件
vim test.txt
随便写一些内容
查看状态
git status      看到有一个待添加的文件texs.txt了
添加test.txt让git追踪
git add test.txt
提交到版本库,并写上备注信息
git commit test.txt -m ‘just a test’
把他推送到服务器的版本库中去
git push origin master

未分类

git client

未分类

git commit

已经推送到服务器端区了。。。接下来去服务器端看看有木有

刚才俺们在服务器端创建版本库时用的是 git init –bare project.git 加了个–bare就是创建一个裸仓库,没有工作区哒,所以这里只记录了文件的改动,要看是不是同步过来了,需要在git clone一次,看是不是这一次有test.txt啦

未分类

未分类

git clone [email protected]:/srv/git/project.git,输入密码后,开始下载代码了,果然master分支已经有test.txt啦.
git log查看一下提交记录,在mon feb 2 09:47:46 2015 +0800的这个,邮件为xxx的作者xxx提交哒。因为windows客户端配置的git是偶滴工作邮件和姓名,就打码了,ok,私有git搭建完成。

git的删除操作

rm test.txt
git status
$ git rm test.txt
rm 'test.txt'
git add -u
$ git commit -m "remove test.txt"
git push

现在,文件就从版本库中被删除了。

另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:

$ git checkout -- test.txt

git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

小结

命令git rm用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。

Jenkins执行git命令报错:Host key verification failed.

在jenkins集成给it,执行git命令测试如下:

git ls-remote -h [email protected]:username/myproject.git HEAD

报错如下:

Failed to connect to repository : Command "git ls-remote -h [email protected]:cc/myproject.git HEAD" returned status code 128:
stdout:
stderr: Host key verification failed.
fatal: The remote end hung up unexpectedly

原因

这需要使用jenkins用户访问mygti.com的主机添加到

~/.ssh/known_hosts。

解决

切换为jenkins用户:

sudo su -s /bin/bash jenkins

在jenkins用户下执行刚才的git命令:

git ls-remote -h [email protected]:username/myproject.git HEAD

在终端提示如下:

The authenticity of host 'mygit.com (xxx.xxx.xxx.xx)' can't be established.
RSA key fingerprint is 84:8c:14:f2:6f:14:6d:6c:3b:fc:ac:49:a6:7c:7a:41.
Are you sure you want to continue connecting (yes/no)?

输入yes回车。这时,mygit.com就已经添加到~/.ssh/known_hosts。

git 出现 fatal: refusing to merge unrelated histories 错误

引用

git pull 失败 ,提示:fatal: refusing to merge unrelated histories

其实这个问题是因为 两个 根本不相干的 git 库, 一个是本地库, 一个是远端库, 然后本地要去推送到远端, 远端觉得这个本地库跟自己不相干, 所以告知无法合并

具体的方法, 一个种方法: 是 从远端库拉下来代码 , 本地要加入的代码放到远端库下载到本地的库, 然后提交上去 , 因为这样的话, 你基于的库就是远端的库, 这是一次update了

第二种方法:
使用这个强制的方法

git pull origin master --allow-unrelated-histories

后面加上 --allow-unrelated-histories , 把两段不相干的 分支进行强行合并

后面再push就可以了 git push gitlab master:init

gitlab是别名 , 使用

Java代码
git remote add gitlab ssh://[email protected]:50022/opt/gitrepo/withholdings/WithholdingTransaction

master是本地的branch名字
init是远端要推送的branch名字

本地必须要先add ,commit完了 才能推上去

关于这个问题,可以参考http://stackoverflow.com/questions/37937984/git-refusing-to-merge-unrelated-histories。

在进行git pull 时,添加一个可选项

git pull origin master --allow-unrelated-histories

git切换分支提示失败(The following untracked working tree files would be overwritten by checkout)

git切换分支的时候报:The following untracked working tree files would be overwritten by checkout

解决方法:

1、

git rm –cached

2、

git clean -d -fx “”

-x means ignored files are also removed as well as files unknown to git.

-d means remove untracked directories in addition to untracked files.

-f is required to force it to run.

git与github远程连接代码库使用笔记

一、安装与账号添加

1. git安装

目前windows版本的git有几种实现,但我们选择msysgit发行版,这是目前做得兼容性最好的。下载地址:http://code.google.com/p/msysgit/downloads/list

2. 生成SSH密钥

ssh-keygen -C '[email protected]' -t rsa

相关内容会存放在:C:Usersuser.ssh之中,有id_rsa,id_rsa.pub

3. 在github中验证

来到自己的github账户:
点击右上角的Edit your profile—> Account Settings—>SSH Public keys —> new ssh key
然后输入id_rsa.pub之中:

未分类

在git bash中执行以下命令完成:

ssh -T [email protected]

4. git本地构建github库

先在自己的github中创建一个Repository,然后在本地git中加入自己的信息:

git config --global user.name "maz"
git config --global user.email "[email protected]"

.

二、git的使用

譬如你的项目为:m/project

1. 添加文件

$ mkdir ~/project //创建一个项目hello-world
$ cd ~/project //打开这个项目
$ git init    //初始化 
$ touch README
$ git add README   //更新README文件
$ git commit -m 'first commit' //提交更新,并注释信息“first commit” !!! 修改code的关键
$ git remote add origin [email protected]:mattzheng/tensorflow.git //连接远程github项目  
$ git push -u origin master   //将本地项目更新到github项目上去 ,更新+修改

add README 是把文件上传到一个临时空间中,然后git commit才确认更新。
确认更新之后,需要git push 才能更新github上的内容。
其中:master 是原始的分支,可以直接创建,origin 是别名
其中:git commit -m ‘first commit’ 更新并注释

2. 分支的使用

创建分支

最开始只有一条分支:master

# 第一种方法:
git checkout -b dev 创建一个新的分支:dev + 并来到新的分支  
# 第二种方法:
git branch dev  # 创建
git checkout dev #来到dev分支
git checkout master # 来自master分支

查看分支

# 查看分支
git branch
git add readme.txt
git commit -m "注释:提交到dev分支"
git push -u origin dev

合并分支

要现在原来的分支中提交:

git push -u origin dev

然后再回到主分支master,然后merge起来:

git merge dev

删除分支

git branch -d dev

3. 回滚与状态查询

git status  # 已加载(staged)和未加载(unstaged)文件的状态、提交等,你可以询问git的状态

4. 取得远程代码库的一份本地拷贝

如果你还没有一份远程代码库的本地版本(例如,如果你在另一台机器上开始工作,这台机器上还没有用过这个项目),你首先需要拷贝(clone)它。去到你的代码库想要拷贝到的文件夹下,并发送:

git clone https://[email protected]/your_username/name_of_remote_repository.git

5. git删除文件

参考:https://www.jianshu.com/p/c3ff8f0da85e

删除本地文件,但是未添加到暂存区;
删除本地文件,并且把删除操作添加到了暂存区;
把暂存区的操作提交到了本地git库;
把本地git库的删除记录推送到了远程服务器github。

删除缓存区一个文件:

git rm test.txt

删除缓存区一个文件夹:

git rm test -r -f

同步删除操作到远程分支:

git commit -m "delete raindow"  

延伸一:git push origin master 报错:

$ git push origin master
To github.com:xiaoyangLee/LearnJava.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to '[email protected]:xiaoyangLee/LearnJava.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

原因是远程仓库中的文件和我们本地的仓库有差异,例如你的远程仓库有个文件Readme.md,但是本地仓库却没有,就可能会出现这种情况。

之所以出现这种情况,原因多种多样,例如你直接使用了github上传文件,或者像我一样,这次使用了另外一个系统推送了文件,导致了此问题的出现。解决办法显然有,把本地仓库删了再git clone一个,但是这种方法显然不可取….

解决办法:使用git pull 合并分支

git pull --rebase origin master

git找回工作区删除的文件

一不小心删除了一个文件怎么办?如果不小心删除一个文件,应该看到这样的提示:

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        deleted:    app/Theme.php

此时直接git checkcout是不行的,应该先git reset HEAD app/Theme.php。注意看提示其实已经说了。
测试你再一次git status:

On branch master
Your branch is up-to-date with 'origin/master'.
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)

        modified:   app/Http/Controllers/Controller.php
        deleted:    app/Theme.php
        modified:   readme.md
        modified:   resources/views/show_partials/item_themes.blade.php
        modified:   resources/views/wlddy/show.blade.php
        modified:   resources/views/wlddy/wlddyform.blade.php
        modified:   resources/views/wlj/wljform.blade.php

修改已经到了not staged的分组了。这个时候,你再git checkout Apptheme.php就可以了!

Git 清理历史提交文件缓存

在刚开始使用 git 的过程中,由于对 git 的工作方式不甚了解,总会产生一些很傻很天真的操作。比如,为了方便项目读取,将二进制文件和代码一起提交到了 git 仓库;亦或者一不小心,将本地打出来的部署包一同提交到了 git 仓库,导致整个项目庞大无比,别人在克隆项目时苦不堪言。虽然可以重建项目,但是又不想丢弃提交记录,该怎么解决呢?

其实我们可以通过 git 命令,来清除文件缓存,而不清除提交记录。

比如,当初为了方便部署,将应用部署包放入 files 文件夹一同提交到了 git 仓库,现在虽然已经删除部署包后重新提交,但是部署包依然后存在于提交记录(以便回退)。我们可以按以下步骤清除指定文件缓存。

步骤 1:整理需要删除缓存的包及路径

整理出包相对于项目的路径。比如,整理出路径如下:

roles/tomcat/files/apache-tomcat-7.0.52.tgz
roles/GraphicsMagickDeployment/files/ImageServer.tar.gz
roles/GraphicsMagickDeployment/files/probe.tar.gz
roles/java/files/jdk1.7.0_51.tgz
roles/tomcat-yuminstall/files/apache-tomcat-7.0.52.tgz
roles/redis/files/redis-2.8.13.tgz
roles/zookeeper/files/zookeeper-3.4.6.tar.gz

步骤 2:执行命令清除缓存

清除命令如下:

git filter-branch --index-filter 
'git rm --cached --ignore-unmatch 
roles/tomcat/files/apache-tomcat-7.0.52.tgz 
roles/GraphicsMagickDeployment/files/ImageServer.tar.gz 
roles/GraphicsMagickDeployment/files/probe.tar.gz 
roles/java/files/jdk1.7.0_51.tgz 
roles/tomcat-yuminstall/files/apache-tomcat-7.0.52.tgz 
roles/redis/files/redis-2.8.13.tgz 
roles/zookeeper/files/zookeeper-3.4.6.tar.gz' 
-f -- --all

执行后, git 会遍历所有的提交,删除相关记录及文件(只删除提交记录中的文件记录,并不会删除整个提交),所以过程需要等待。

需要注意的是,清除后的文件无法通过提交记录还原。

步骤 3:删除原有项目并重建

需在 git 仓库上删除原有项目并重新提交,才可顺利进行,否则会出新冲突。

步骤 4:删除本地项目后重新克隆

若不删除本地项目,重新拉会导致冲突,所以执行操作前,最好先通知本地人员提交当前版本,并等待操作完成。

Git只拉取部分代码

在某些情况下,我们会有从git上拉取部分文件的需求。

下面脚本就演示了如何从gitlab中只拉取需要的文件:

#!/bin/bash
# 拼接git地址,并加上权限
GITLAB_PROTOCOL=https://
GITLAB_USER=xxx
GITLAB_PASSWD=xxx
GITLAB_ADDRESS=git.xxx.com
GITLAB_GOURP=xxxxxx
PROJECT_NAME=xxxxxx
CLONE_ADDRESS=$GITLAB_PROTOCOL$GITLAB_USER':'$GITLAB_PASSWD'@'$GITLAB_ADDRESS'/'$GITLAB_GOURP'/'$PROJECT_NAME'.git'

# 初始化
git init 
# 添加源
git remote add origin $CLONE_ADDRESS
# 配置sparsecheckout为true
git config core.sparsecheckout true
# 把要拉取的文件目录加入到.git/info/sparse-checkout文件中
echo "dockerfile*" >> .git/info/sparse-checkout
echo "*.sh" >> .git/info/sparse-checkout
# 拉取文件
git pull origin master

pull完成之后所有dockerfile和脚本文件就会被下载到本地。

Git 忽略提交 .gitignore

在使用Git的过程中,我们喜欢有的文件比如日志,临时文件,编译的中间文件等不要提交到代码仓库,这时就要设置相应的忽略规则,来忽略这些文件的提交。

Git 忽略文件提交的方法

有三种方法可以实现忽略Git中不想提交的文件。

在Git项目中定义 .gitignore 文件

这种方式通过在项目的某个文件夹下定义 .gitignore 文件,在该文件中定义相应的忽略规则,来管理当前文件夹下的文件的Git提交行为。

.gitignore 文件是可以提交到共有仓库中,这就为该项目下的所有开发者都共享一套定义好的忽略规则。

在 .gitingore 文件中,遵循相应的语法,在每一行指定一个忽略规则。如:

*.log
*.temp
/vendor

在Git项目的设置中指定排除文件

这种方式只是临时指定该项目的行为,需要编辑当前项目下的 .git/info/exclude 文件,然后将需要忽略提交的文件写入其中。

需要注意的是,这种方式指定的忽略文件的根目录是项目根目录。

定义Git全局的 .gitignore 文件

除了可以在项目中定义 .gitignore 文件外,还可以设置全局的 git .gitignore 文件来管理所有Git项目的行为。这种方式在不同的项目开发者之间是不共享的,是属于项目之上Git应用级别的行为。

这种方式也需要创建相应的 .gitignore 文件,可以放在任意位置。然后在使用以下命令配置Git:

git config --global core.excludesfile ~/.gitignore

Git 忽略规则

详细的忽略规则可以参考官方英文文档: https://git-scm.com/docs/gitignore

Git 忽略规则优先级

在 .gitingore 文件中,每一行指定一个忽略规则,Git 检查忽略规则的时候有多个来源,它的优先级如下(由高到低):

  • 从命令行中读取可用的忽略规则
  • 当前目录定义的规则
  • 父级目录定义的规则,依次地推
  • $GIT_DIR/info/exclude 文件中定义的规则
  • core.excludesfile中定义的全局规则

Git 忽略规则匹配语法

在 .gitignore 文件中,每一行的忽略规则的语法如下:

  • 空格不匹配任意文件,可作为分隔符,可用反斜杠转义
  • # 开头的文件标识注释,可以使用反斜杠进行转义
  • ! 开头的模式标识否定,该文件将会再次被包含,如果排除了该文件的父级目录,则使用 ! 也不会再次被包含。可以使用反斜杠进行转义
  • / 结束的模式只匹配文件夹以及在该文件夹路径下的内容,但是不匹配该文件
  • / 开始的模式匹配项目跟目录
  • 如果一个模式不包含斜杠,则它匹配相对于当前 .gitignore 文件路径的内容,如果该模式不在 .gitignore 文件中,则相对于项目根目录
  • ** 匹配多级目录,可在开始,中间,结束
  • ? 通用匹配单个字符
  • [] 通用匹配单个字符列表

常用匹配示例

  • bin/: 忽略当前路径下的bin文件夹,该文件夹下的所有内容都会被忽略,不忽略 bin 文件
  • /bin: 忽略根目录下的bin文件
  • /*.c: 忽略 cat.c,不忽略 build/cat.c
  • debug/*.obj: 忽略 debug/io.obj,不忽略 debug/common/io.obj 和 tools/debug/io.obj
  • **/foo: 忽略/foo, a/foo, a/b/foo等
  • a/**/b: 忽略a/b, a/x/b, a/x/y/b等
  • !/bin/run.sh: 不忽略 bin 目录下的 run.sh 文件
  • *.log: 忽略所有 .log 文件
  • config.php: 忽略当前路径的 config.php 文件

.gitignore规则不生效

.gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。

解决方法就是先把本地缓存删除(改变成未track状态),然后再提交:

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