【问题标题】:Copy a git repo without history复制没有历史记录的 git repo
【发布时间】:2015-06-04 19:17:57
【问题描述】:

我想在 GitHub 上公开一个私有存储库。但是,一些初始提交包含我不想公开的信息(硬编码凭据等)。

在不包括部分或全部提交历史的情况下,公开最新提交(我真的不需要或不希望公共存储库中的先前提交)的最简单途径是什么?

【问题讨论】:

  • 为什么不创建一个新的存储库?
  • @Stephan 我可以创建一个新的存储库,但是如何从旧存储库中获取最新状态并将其提交到新存储库?
  • 您可以删除 .git 文件夹,然后在您的源文件夹上再次执行 git init
  • 删除 .git 文件夹会使您的两个存储库不兼容,您将无法从一个合并到另一个
  • 你不能变基吗?您实际上只是压缩所有旧提交,然后(强制)推送。

标签: git github git-fork


【解决方案1】:

cloning时可以限制历史的深度:

--depth <depth>
Create a shallow clone with a history truncated to the specified 
number of revisions.

如果您想要有限的历史记录,请使用它。

【讨论】:

  • 给这个人一个饼干(以标记这个答案正确的形式):)
  • 这并没有解决问题所暗示的预期用途,即能够推送到远程公共存储库。尝试推送浅克隆会导致 shallow update not allowed
  • 是以后使用 git pull 命令后保持深度还是历史再次堆积?
  • @Salar 深度仅在克隆​​时相关。在那之后,历史就是这样。听起来您想定期“清理历史”。我不明白你为什么要这样做,但新的克隆或压缩是我想到的解决方案。
【解决方案2】:

使用以下命令:

git clone --depth <depth> -b <branch> <repo_url>

地点:

  • depth 是您想要包含的提交数量。即,如果您只想要最新的提交,请使用 git clone --depth 1
  • branch 是您要从中克隆的远程分支的名称。即,如果您想要来自 master 分支的最后 3 次提交,请使用 git clone --depth 3 -b master
  • repo_url 是您的存储库的网址

【讨论】:

  • +1 到主要答案,但也到这个解释关于选择你希望深度应用到哪个分支 - 我知道这是克隆命令的一部分 - 但它把它们联系在一起在我简单的头脑中很好......我喜欢简单:)
  • 最佳答案!
  • 这如何回答这个问题?所有这些都是在本地创建一个浅克隆,但是然后呢?你如何将这个历史有限的本地副本复制到新的仓库中?
  • @BradDaBug 提出了一个有效的观点。我按照上面的说明将深度限制为 1,然后更改了远程原点,然后尝试推送到我的新仓库。但是,我收到一条错误消息,指出 shallow update not allowed。我发现这个stack overflow answer 在这种情况下很有用。
【解决方案3】:

删除.git 文件夹可能是最简单的方法,因为您不想要/不需要历史记录(正如斯蒂芬所说)。

因此您可以从您的最新提交中创建一个新的存储库: (How to clone seed/kick-start project without the whole history?)

git clone <git_url>

然后删除.git,然后运行

git init

或者,如果您想重复使用当前的存储库: Make the current commit the only (initial) commit in a Git repository?

然后按照上述步骤:

git add .
git commit -m "Initial commit"

推送到您的仓库。

git remote add origin <github-uri>
git push -u --force origin master

【讨论】:

  • 这应该是被选中的答案
【解决方案4】:
#!/bin/bash
set -e

# Settings
user=xxx
pass=xxx
dir=xxx
repo_src=xxx
repo_trg=xxx
src_branch=xxx

repo_base_url=https://$user:$pass@bitbucket.org/$user
repo_src_url=$repo_base_url/$repo_src.git
repo_trg_url=$repo_base_url/$repo_trg.git

echo "Clone Source..."
git clone --depth 1 -b $src_branch $repo_src_url $dir

echo "CD"
cd ./$dir

echo "Remove GIT"
rm -rf .git

echo "Init GIT"
git init
git add .
git commit -m "Initial Commit"
git remote add origin $repo_trg_url

echo "Push..."
git push -u origin master

【讨论】:

  • --depth 1 在这种情况下是不必要的,因为使用rm -rf .git 也会删除历史记录
  • 我想我会这样做:git clone --depth 1 -b $src_branch $repo_src_url $dir &amp;&amp; cd ./$dir &amp;&amp; git commit --amend --author "Some One &lt;some@one.com&gt;" -m "Initial Commit" &amp;&amp; git remote set-url origin $repo_trg_url &amp;&amp; git push -u origin master
  • @rayphi 是的,--depth 1 是不必要的,但它也是无害的,它节省了一点网络带宽(没有必要获取您将要删除的历史记录)
  • 如果你想保持你的存储库兼容,我不建议这样做。
  • 删除 .git 也会删除所有的 git 钩子。
【解决方案5】:

您可以将 GitHub 存储库设置为模板(通过转到设置并选择存储库名称下方的选项)。然后代码页面上会出现一个“使用此模板”的按钮。这会复制所有文件,但会删除所有历史记录,如果您将原始存储库设为私有,则不会在存储库名称下显示任何详细信息(请注意,它会显示在您的网站上,因为您拥有这两个文件,但不属于其他任何人) .只有当 repo 公开时,repo 名称下才会显示指向原始 repo 的链接。

【讨论】:

    【解决方案6】:

    首先,我应该说,如果只有少数提交包含敏感信息,您最好使用git rebase -i 删除它们。但是当这些文件经常被触及时,这可能会变得复杂。此外,使用git-rebase 很难摆脱初始提交,因此如果您的初始提交包含您要删除的内容,那么事情会变得更加困难。

    但无论如何,上述所有将整个 repo 折叠成一个提交的答案似乎都过于复杂,而且涉及大量中间目录并且可能会破坏存储在 .git 中的所有其他配置,而且速度也会很慢。

    一种更快的方法是创建一个与现有提交完全匹配的孤立提交,例如:

    $ TREE=`git cat-file -p master |sed '1,/^$/s/^tree //p;d;'`
    $ COMMIT=`echo Truncated tree | git commit-tree $TREE`
    $ git branch truncated-master $COMMIT
    

    根据需要替换 mastertruncated-master,并根据需要更改提交消息。如果您真的很勇敢,请继续:

    $ git branch backup-master-just-in-case-i-regret-it-later master
    $ git push -f origin truncated-master:master
    

    但是,如果我是你,我真的会避免做这最后一步,因为这会给当前使用 repo 的每个其他人带来问题。相反,只需切换到使用这个新分支(可能有更好的名称),不要宣传旧分支。

    【讨论】:

      【解决方案7】:

      这不正是压缩 rebase 的作用吗?只需压缩除最后一次提交之外的所有内容,然后(强制)推送它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-06
        • 2022-06-14
        • 1970-01-01
        • 2020-11-20
        • 1970-01-01
        • 2011-06-06
        相关资源
        最近更新 更多