V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  Yancey  ›  全部回复第 4 页 / 共 8 页
回复总数  150
1  2  3  4  5  6  7  8  
2016 年 8 月 19 日
回复了 qingfengzm 创建的主题 酷工作 [美团&点评] 2017 校招内推开始了
哈哈。哪都有你
@mrsatangel 感谢。你的方案可行。

我原本以为本地截断后,不能强行推送到远端。原来是可以的。

不过你提到
“为当前的这个 branch 新建一个临时的 branch:`git branch tmp`,然后将 tmp branch 推送到远程的 repo 里想要更新的 branch (如 master ):`git push <remoteRepoName> tmp:<remoteBranchName>`,此时远程 repo 里面的**&lt;remoteBranchName&gt;**已经将**newRoot**之前的所有 commit 对象删除。”

感觉这个 tem branch 是多余的吧。直接强推截断的 master 就可以的。


另外对你的答案补充下;
假如你有如下的分支结构图

http://ww1.sinaimg.cn/large/bd128c47gw1f6nac39th4j20ff08jjrl.jpg

现在想从"57dd13f even"这个点截断。保留这个点上面的所有分支和 commit
首先需要 git push origin :test 将 test 分支删除。也就是说截断点以下的所有都删除。
再者 将截断点以上的所有分支都在本地有追踪分支 git checkout -b new origin/new

之后就执行

“在`.git/info/`下建立`grafts`文件,在其中输入`newRoot`对象的 SHA1 值,保存。此时使用`git log`命令应该只能看到`newRoot`的 commit 记录。
之后使用`git filter-branch`使这个新建的 root 生效. ”


最后执行
将本地所有分支都强推到远端一遍。
本例就是 git push --force origin master:master 和 git push --force origin new:new


哦对了,还要删除 original 文件夹保存的临时记录
rm -r .git/refs/original/


最后效果:

http://ww1.sinaimg.cn/large/bd128c47gw1f6nbkmr397j20f302omx3.jpg



其实这样的好处还有一个就是,所有 clone 这个仓库的本地仓库都可以执行一个相同的脚本。这样就不用大家都重新 clone 了,本地的 branch 和没有推送的 commit 也可以保留。


不知道理解对不对。可以再讨论。
@SourceMan 我这边磁盘小。。编译的时候拉十几个工程也是几个 G
@skydiver 几百个 branch 几千个 commits 怎么 rebase -i 不行吧
@kukat 编译没关系。。这不是编译服务器磁盘小么。装不下所有带.git 文件夹的工程了
@SpicyCat 因为是 android 项目。我查了下大文件, 基本是图片或 jar 包。这些图片或 jar 包经过迭代现在很可能已经不再使用了,但是还在仓库历史里面。所以.git folder 比较大。

看来这问题是无解了。
@bjzhou1990 恩。是个好办法。
我测试还是遇到问题
1. 在服务端。我自己测试的时候是通过 git init --bare 来建仓库的,所以服务端 git checkout --orphan 命令没法使用。。
2. 服务端进行操作后,所有的本地仓库都要克隆一遍。。


我考虑的办法。
假设我们要截断的点 hash 值为 1234abc
在服务端:
echo 1234abc > info/grafts
git filter-branch -- --all
以及后续删除 grafts 和 gc 操作

写个脚本让所有本地克隆的都执行。内容大概是
echo 1234abc > .git/info/grafts
git filter-branch -- --all
删除 grafts
git fetch --all

目的是让本地和服务端改变一模一样。这样本地的分支。没有 push 的 commits 都可以保留


还是遇到问题

在服务端;
执行 git filter-branch -- --all 之前要将所有的 1234abc 之前的分支都删除。

在本地
git filter-branch -- --all 执行的时候 origin/xx 这种分支也会被操作。总之结果很混乱。不是想要的效果


看来真的是无解啊。。
@zzn 背景是这样。 最开始一个主工程。然后 clone 了好几份工程作为不同的库(这个点我们暂定位 date 点)。后来这些库往不同业务发展。所以想将 date 点之前的所有 commit 删除。毕竟后来分成不同库了, date 之前和这些库完全没有啥关系。。
@bjzhou1990 我就是参考这个。如图的 git 结构,遇到问题是,因为截断点之前还有 commit 。会导致截断后除了 之后想要的 commit 线外。 branch1 branch2 不会被操作。保持原样。 分支混乱。。
@kukat 你这还不减? 我们一个工程就这么大。总共几十个工程。。。源码编译的时候硬盘受不了
@Yancey 对啊。截断导致结果就是从截断到现在最新的 commits 所有的 SHA1 值都会改变。。因为是公开的项目。很多人已经克隆了。。对本地的影响很大。
@forcecharlie
@forcecharlie 对啊。截断的效果就是从截断到现在最新的 commits 所有的 SHA
@vitovan 因为丢掉历史,会让从截断的地方到现在最新的 commit 的 ID 都改变,也就是相当于把所有的留下的 commits 都重新提交了一遍。 这个时候服务端和本地 commits 没有一个是能对应上的。强行 push 我们期望的效果是 服务端的 commits 和分支记录 都完全被更改过的本地 commits 替换掉。。但是 git 并不会这样。
@mengzhuo commits 是确定不会再用的, 所以要删掉。。 gc 一次 200M 顶多到 160M 。
@lijianying10 这种治标不治本啊。。
@vitovan sorry 看错,以为你说的 reset 。 rebase 是可以。但是一般服务器的仓库是一个裸仓库(没有工作目录), git rebase , git branch 命令都没法使用。。如果在本地操作,强推到服务端。所有分支都会混乱、、
@vitovan rebase 不行。。 rebase 是当前的回到某个时间点或 commits 。 现在是要把某个时间点之前的丢掉
1  2  3  4  5  6  7  8  
关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   2549 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 16ms · UTC 11:02 · PVG 19:02 · LAX 03:02 · JFK 06:02
♥ Do have faith in what you're doing.