状況は次のとおりです。
Github.comにオープンソースアプリの公開リポジトリがあります。ただし、公開されない特定のコードを記述したいと思います(アプリケーションの商用バージョンで使用する可能性があります)。
同じリポジトリを使用できると思い、Gitリポジトリにプッシュしない「プライベート」ブランチを作成しました。
しかし、間違いは起こります。 gitがブランチをリモートサーバーにプッシュすることを禁止する方法はありますか?
この状況に対処するためのより良い方法があれば、もちろん私はどんな提案も歓迎します。
少しハックな解決策:GitHubに実際のブランチと同じ名前のダミーブランチを作成し、早送りマージにならないようにします。そうしないと、プッシュ操作は失敗します。
これが例です。
$ git clone [email protected]:user/repo.git
$ cd repo
$ git checkout -b secret
$ echo "This is just a dummy to prevent fast-forward merges" > dummy.txt
$ git add .
$ git commit -m "Dummy"
$ git Push Origin secret
ダミーブランチが設定されたので、ローカルで再作成して、GitHubのブランチから分岐させることができます。
$ git checkout master
$ git branch -D secret
$ git checkout -b secret
$ echo "This diverges from the GitHub branch" > new-stuff.txt
$ git add .
$ git commit -m "New stuff"
誤ってプッシュしようとすると、早送り以外のマージエラーで失敗します。
$ git Push Origin secret
To [email protected]:user/repo.git
! [rejected] secret -> secret (non-fast forward)
error: failed to Push some refs to ‘[email protected]:user/repo.git’
dontpushthis
というブランチを使用して、pre-Push
フックアプローチがどのように機能するかを次に示します。
このファイルを.git/hooks/pre-Push
として作成します。
if [[ `grep 'dontpushthis'` ]]; then
echo "You really don't want to Push this branch. Aborting."
exit 1
fi
これは、プッシュされている参照のリストが標準入力で渡されるために機能します。したがって、これはgit Push --all
もキャッチします。
実行可能にします。
すべてのローカルリポジトリでこれを実行します。
そのブランチにプッシュしようとすると、次のように表示されます。
$ git checkout dontpushthis
$ git Push
You really don't want to Push this branch. Aborting.
error: failed to Push some refs to 'https://github.com/stevage/test.git'
明らかに、これは見た目と同じくらい単純で、「dontpushthis」という名前のブランチをプッシュすることを防ぐだけです。したがって、master
などの重要なブランチに直接プッシュすることを避けようとしている場合に役立ちます。
機密情報の漏洩を防ぐという問題を解決しようとしているのなら、それだけでは不十分かもしれません。たとえば、dontpushthis
からサブブランチを作成した場合、そのブランチは検出されません。より高度な検出が必要になります。たとえば、「dontpushthis」ブランチのコミットが現在のブランチに存在するかどうかを確認できます。
もう一度質問を見ると、この場合のより良い解決策は次のようになると思います。
git remote rm Origin
)を削除します。git pull https://github.com/myproj/mypublicrepo
を実行するだけです。このように、プライベートリポジトリの作業ディレクトリには、プッシュできる場所がありません。あなたは本質的に、公開情報から非公開への一方向のバルブを持っていますが、戻ってはいけません。
@ steve-bennettからの.git/hooks/pre-Pushスクリプトの修正
#!/usr/bin/bash
branch_blocked=mine
if grep -q "$branch_blocked"; then
echo "Branch '$branch_blocked' is blocked by yourself." >&2
exit 1
fi
現在のgitバージョンで提供されているプレプッシュの例を単純に使用してみませんか?
アイデアは、Word PRIVATE:
でプライベートブランチの最初のコミットのコミットメッセージを開始することです。
プレプッシュスクリプトを設定した後、プッシュごとに、プッシュされた参照のすべてのログのコミットメッセージをチェックします。 PRIVATE:で始まる場合、プッシュはブロックされます。
手順は次のとおりです。
.git/hooks/pre-Push
にファイルを作成しますその中の次のスクリプトを過ぎて
#!/bin/sh
remote="$1"
url="$2"
z40=0000000000000000000000000000000000000000
IFS=' '
while read local_ref local_sha remote_ref remote_sha
do
if [ "$local_sha" = $z40 ]
then
# Handle delete
:
else
if [ "$remote_sha" = $z40 ]
then
# New branch, examine all commits
range="$local_sha"
else
# Update to existing branch, examine new commits
range="$remote_sha..$local_sha"
fi
# Check for WIP commit
commit=`git rev-list -n 1 --grep '^PRIVATE:' "$range"`
if [ -n "$commit" ]
then
echo "Error: Found PRIVATE commit in $local_ref."
echo "The commit is in the range $range."
echo "NOT pushing!"
exit 1
fi
fi
done
exit 0
remote="$1"
url="$2"
失敗の例
$ git Push Origin private/old-kalman-filter
Found PRIVATE commit in refs/heads/myforbiddenbranch, the commit is in the range
a15c7948676af80c95b96430e4240d53ff783455. NOT PUSHING!
error: failed to Push some refs to 'remote:/path/to/remote/repo'
ブランチを再びプッシュ可能にするには、フックを削除するか、コミットメッセージを変更して禁止されているWordを削除します。
このスクリプトは、remote_ref
をチェックすることにより、1つの禁止されたリモートのみを考慮するように変更できます。ただし、その場合は、このブランチの受信が許可されているすべてのリポジトリにこのフックをコピーすることを忘れないでください。
リモートリポジトリに存在しないブランチを作成できます。
そうすれば、次のようになります。
git Push Origin
リモートリポジトリに存在するブランチのみをプッシュします。
また、ブランチを作成した後、.git/config
(ローカルリポジトリディレクトリ内)ファイルを調べます。すべてのローカルブランチに異なるリモートリポジトリを割り当てることができることがわかります。このブランチを個別の(プライベート)リポジトリに割り当てることでこれを利用できますが、これはユニバーサルソリューションではありません(明示的に注文した場合、またはコマンドgit Push Origin
によって、ブランチをOriginリモートにプッシュできます)。
複数の解決策があります:
git-Push
のラッパーを記述して、gitPushによるプッシュを防止しますGitHubを使用する場合は、GitHubにブランチと同じ名前のブランチを作成できます。コミットをプッシュする必要はありません。マスターなどから空のブランチを作成するだけです(GitHubインターフェースで、「ブランチ」ポップアップにブランチを入力してcreate branch <branch-name>
をクリックすることで実行できます)。
次に、リポジトリのブランチ設定(https://github.com/<user>/<repo>/settings/branches/<branch-name>
など)に移動し、ブランチのブランチ保護を有効にします。必ずすべてのチェックボックスをオンにしてください。特に、ブランチを直接プッシュすることを禁止する[レビューが必要]または[ステータス]チェックボックスをオンにしてください(プルリクエストからプッシュする必要があります)。管理者。
その場合、GitHubは、-f
を使用していても、ブランチにプッシュすることを許可しません。次のようなメッセージが表示されます
$ git Push -f Origin private
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 981 bytes | 981.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
remote: error: GH006: Protected branch update failed for refs/heads/private.
remote: error: At least 1 approving review is required by reviewers with write access.
To github.com:<user>/<repo>.git
! [remote rejected] private -> private (protected branch hook declined)
error: failed to Push some refs to '[email protected]:<user>/<repo>.git'