6

個人的な git ワークフローを、もう少し扱いやすいものに改良しようとしています。

この投稿の目的で git をどのように使用しているかの背景を次に示します。

  • リポジトリで作業する唯一の開発者。

  • ローカル マシンに格納されているリポジトリの単一のコピー。

  • ブランチは「dev」と「master」の 2 つだけです。

  • すべての作業は「dev」で行われます。

私が達成しようとしているのは、「マスター」ブランチに対して行われたコミットのみが、確認済みの安定した「開発」コードに基づく実稼働バージョンであるという点に到達することです。

事実上、私がやろうとしていることは次のとおりです。

  1. 「dev」のすべてがテストされ、準備が整ったら、「master」を「dev」ブランチ ファイル ツリーの正確なクローンに更新します。

  2. バージョン番号などを更新するために「マスター」にマイナーな変更を加えます...

  3. 更新された「マスター」ブランチにコミットします。

  4. 「master」ブランチから新しいタグを作成します。

私が最初のステップに近づいている方法は、「マスター」ブランチをチェックアウトしてから実行することです。

'git diff master dev | git apply -'

私が理解していることから、これは「マスター」のすべてを効果的に吹き飛ばし、ツリー全体を「開発」の内容に置き換えます。「git status」を実行すると、これが上記の #1 に基づいて期待されていることを示しているように見えます。

では、最初の質問:それは正しいですか?

「マスター」ブランチがこれらの更新を受け取った後、スクリプトを実行してファイルのバージョン番号を更新します。次に、標準の「git add」を実行します。そして「git commit -a」ですべての変更を追加します。最後に、新しいタグを作成し、「dev」ブランチに戻ってコーディングを再開します。

では、もう 1 つの質問:そのプロセスで問題を引き起こすものはありますか?

更新:これを初めて入れるべきでしたが、単純にマージを使用していない理由は、マスターのバージョン番号を変更してから、dev の変更とマージしようとすると、マージの競合が発生するためです。それらが無関係であることはわかっていますが、それでもプロセスが停止します。以前に「merge -Xtheirs {branch}」を使用して対処したことがありますが、それについてもわかりません。

更新 2: ここでは、動作しないことがわかっているものをいくつか示します。Mac OSX で動作する bash スクリプトをまとめました。最初のものはマージを使用しようとします:

#!/bin/bash -x

####################
### file: merge1 ###
####################

### clear out the old stuff so you can rerun
rm -rf .git
rm *.txt

### setup the repository
git init

### ignore merge and output files for clarity sake
echo -e "output*\nmerge*" > .gitignore
git add .gitignore

### make the intial commit and move over to dev
git commit -m "Initial commit"
git checkout -b dev

### add stuff to test1.txt in dev
echo -e "FILE1 LINE\nVERSION-XXX\nFILE1 LINE" > test1.txt
echo -e "File2 LINE\nVERSION-XXX\nFILE2 LINE" > test2.txt

### add the files and commit
git add .
git commit -m "Created test1.txt and test2.txt in dev."

### output the state of test1.
cat test1.txt > output-dev-test1-a.txt
cat test2.txt > output-dev-test2-a.txt

### move to master and do a first merge which will work
git checkout master
git merge dev

### Update the version numbers in master and commit it
sed -i "" -e 's/VERSION-XXX/VERSION-1.0/g' test*.txt
git commit -am "Updated version to 1.0 on master"

cat test1.txt > output-master-test1-a.txt
cat test2.txt > output-master-test2-a.txt

### switch back to dev and commit an update to test1.txt
git checkout dev
sed -i "" -e 's/LINE/CHANGED/' test*.txt
git commit -am "Updated content in test*.txt on dev"

### dump test1.txt for reference.
cat test1.txt > output-dev-test1-b.txt
cat test2.txt > output-dev-test2-b.txt

### swtich back to master
git checkout master

######################################################################
### BREAK
######################################################################

### this is where the merge fails because of a conflict
git merge dev

これを試したもう 1 つの方法は、-Xtheirs を使用することでした。これは、最初は機能しているように見えますが、すべてが更新されるわけではありません。これを確認するには、上記の BREAK の後の最後の数行を削除して、次のように置き換えます。

### merge with -Xtheirs works here. Proper version "XXX" is showing.
git merge -Xtheirs dev

### but if we update the version number one more time on master
sed -i "" -e 's/VERSION-XXX/VERSION-2.0/g' test*.txt
git commit -am "Updated version to 2.0 on master"

### dump reference file
cat test1.txt > output-master-test1-b.txt
cat test2.txt > output-master-test2-b.txt

### Now, go back to dev and change something in only one of the files
git checkout dev
sed -i "" -e 's/CHANGED/ALTERED/g' test2.txt
git commit -am "Altered only test2.txt on dev."

cat test1.txt > output-dev-test1-c.txt
cat test2.txt > output-dev-test2-c.txt


### are finally return to master and merge again
git checkout master
git merge -Xtheirs dev

### dump reference file
cat test1.txt > output-master-test1-c.txt
cat test2.txt > output-master-test2-c.txt

競合はありませんが、「output-master-test1-c.txt」には、必要な「VERSION-XXX」ではなく「VERSION-2.0」が表示されます。これは、ファイルに変更がなかったために発生したようです。「output-master-test2-c.txt」ファイルには、予想される「VERSION-XXX」文字列が含まれています。もちろん、問題は、バージョン 3.0 に更新しようとした検索と置換が test1-c で失敗することです。これは、VERSION 文字列の 2.0 部分が認識されないためです。

4

3 に答える 3

7

diff/apply ハックの代わりに実際のマージを使用する必要があります。これは次のように簡単です

[master]$ git merge dev

これを master ブランチ (プロンプトに表示) で実行すると、dev からのすべての変更がマージされます。その後、バージョン番号を更新し、コミットしてタグを作成できます

[master]$ git commit -a -m "New version number."
[master]$ git tag version-1.x

それはそれと同じくらい簡単です。

実際、マスター ブランチはまったく必要ありません。dev に基づいて短期間のリリース ブランチを作成し、そこにタグを作成して、後でブランチを削除できます。

[dev]$ git checkout -b release dev
[release]$ git commit -a -m "New version number."
[release]$ git tag version-1.x
[release]$ git checkout dev
[dev]$ git branch -d release
于 2010-10-30T00:31:50.130 に答える
1

私は非常に似たようなことをしています(私が自分のソフトウェアの唯一の開発者である場合のみ)...

私はマスターブランチでのみ作業しています。そして、さまざまな「バージョン」で、ぶら下がっているブランチを作成します。

これにより、チェックアウトするだけで以前のバージョンに戻すことができます。

A - B - C - D - E - F
     \               \
      1.0             1.1

簡単で、私のニーズには十分です。

以前のバージョンにいくつかのバグ修正を行う必要がある場合は、そのブランチから離れて作業を行います。

于 2010-11-03T21:36:34.900 に答える
0

これにアプローチする別の方法を思いつきました。これは、必要なすべてを実行すると思います。その核心は、マスターで次のことを行うことです。

### pull the diff to make sure there are no conflict
git diff master dev | git apply -

### do merge without commit to make branch tree behave
git merge --no-commit --no-ff -s ours dev

### update the version numbers
sed -i "" -e "s/VERSION-XXX/VERSION-$1/g" *.txt

### now, add everything to master and commit
git add . 
git commit -m "Master commit $1"

これにより、「dev」のすべてのバージョン番号が「XXX」のままであることが確認されますが、「master」のすべてのファイルで適切に更新されます。また、gitk で「master」ブランチの履歴を見ると、特定の「dev」バージョンがどこに追加されたかがわかります。例:

dev:      d1----d2----d3----d4----d5
         /  \           \     \
master: x    m1          m2    m3

このツリーは私が探していたものであり、何が起こっているのかを正確に理解するのを容易にしてくれます。

これは、私がこれをテストして理解するために使用したbashスクリプト(問題がある場合に備えてMac OSXで作成されたもの)です。他の戦略を試すことに関心がある場合は、「doMerge」関数を更新してスクリプトを実行するだけで、何が起こるかを確認できます。

#!/bin/bash

######################################################################
# Setup functions
######################################################################

function doMerge {

  ### add everything in dev
  git add .
  git commit -m "Commiting dev $1"

  ### switch to master
  git checkout master

  ### pull the diff to make sure there are no conflict
  git diff master dev | git apply -

  ### do merge without commit to make branch tree behave
  git merge --no-commit --no-ff -s ours dev

  ### update the version numbers
  sed -i "" -e "s/VERSION-XXX/VERSION-$1/g" *.txt

  ### now, add everything to master and commit
  git add . 
  git commit -m "Master commit $1"

  git tag -m "Created tag v-$a" -a "v-$1"

  ### and then switch back to dev so you are ready to work
  git checkout dev

}


### this just lets you see what's going on in the output
function showReport {

  echo "############################################################"
  echo "##### 'dev' branch files #####"
  echo "############################################################"

  DEVCNT=1
  while [ $DEVCNT -lt 4 ]; do
    cat $DEVCNT.txt
    echo "############################################################"
    let DEVCNT=DEVCNT+1 
  done

  git checkout master


  echo "############################################################"
  echo "##### 'master' branch files #####"
  echo "############################################################"

  MASTCNT=1
  while [ $MASTCNT -lt 4 ]; do
    cat $MASTCNT.txt
    echo "############################################################"
    let MASTCNT=MASTCNT+1 
  done
  echo ""

  git checkout dev

}


######################################################################
# Main
######################################################################

### clear out the old stuff so you can rerun
rm -rf .git
rm *.txt

### setup the repository
git init

### ignore merge and output files for clarity sake
echo "check-history" > .gitignore
git add .gitignore

git commit -m "added .gitignore"

### switch to dev
git checkout -b dev

### add some files
COUNTER=1
while [  $COUNTER -lt 10 ]; do
  echo "File $COUNTER - VERSION-XXX" > $COUNTER.txt
  echo "The quick brown fox jumps over the lazy dog" >> $COUNTER.txt
  let COUNTER=COUNTER+1 
done

### run the diff/apply/merge strategy and show the results
doMerge 1; showReport


echo "File 2 - VERSION-XXX" > 2.txt
echo "New Data" >> 2.txt

git commit -am "dev tmp commit 1"

echo "Additional data" >> 1.txt
echo "Additional data" >> 2.txt

doMerge 2; showReport

sed -i "" -e 's/quick/EXTREMELY FAST/' 3.txt

doMerge 3; showReport

私が言えることから、これは機能します。試してみて、何か発見したらまたここに報告します。もちろん、知っていることがあれば、ハックの少ない他の方法にも興味があります。

于 2010-10-30T17:49:07.137 に答える