Git本地存储库上的单个开发人员的工作流程

时间:2010-10-29 22:30:34

标签: git workflow git-diff

我正在尝试将个人git工作流程改进为更易于处理的事情。

以下是我如何将git用于本文的一些背景知识:

  • 单个开发人员,他是唯一一名在存储库上工作的开发人员。

  • 存储在本地计算机上的存储库的单个副本。

  • 只有两个分支“dev”和“master”。

  • 所有工作都在“dev”上完成。

我想要完成的是达到这样的程度,即对“master”分支进行的唯一提交是基于受限制的稳定“dev”代码的工作生产版本。

实际上,我要做的是:

  1. 当“dev”中的所有内容都经过测试并准备就绪时,请将“master”更新为“dev”分支文件树的精确克隆。

  2. 对“master”进行微小修改以更新版本号等......

  3. 提交更新的“主”分支。

  4. 从“master”分支创建一个新标记。

  5. 我接近第一步的方法是结帐“主”分支,然后运行:

    'git diff master dev | git apply -'
    

    据我了解,这有效地吹走了“master”中的任何内容,并用“dev”的内容替换整个树。运行“git status”似乎表明这正在做出基于上面#1的预期。

    所以,第一个问题:这是正确的吗?

    在“master”分支收到这些更新后,我运行我的脚本来更新文件中的版本号。然后,我只运行一个标准的“git add”。和“git commit -a”添加所有更改。最后,我创建一个新标签并返回“dev”分支再次开始编码。

    所以,另一个问题:该流程中是否有任何问题会导致问题?

    更新:我应该在第一次使用它,但我不是简单地使用merge的原因是更改master上的版本号然后尝试与dev中的更改合并会导致合并冲突。我知道它们无关紧要,但它仍然会阻止这个过程。我之前使用过“merge -Xtheirs {branch}”来处理它,但我也不确定。

    UPDATE2:这里有一些我认识不起作用的东西。我已经整理了一个适用于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
    

    我尝试这种方法的另一种方式是使用-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-2.0'而不是'VERSION-XXX'。这似乎发生了,因为文件没有变化。 'output-master-test2-c.txt'文件具有预期的'VERSION-XXX'标记。当然,问题是尝试更新到3.0版的查找和替换会在test1-c中遗漏,因为它无法识别VERSION sting的2.0部分。

3 个答案:

答案 0 :(得分:7)

您应该使用真正的合并而不是diff / apply hack。这就像

一样简单
[master]$ git merge dev

当你在master分支上运行它(在提示中显示)时,你将合并来自dev的所有更改。之后,您可以更新版本号,提交并创建标签

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

就这么简单。

实际上你根本不需要一个master分支,你可以创建一个基于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

答案 1 :(得分:1)

我做的事非常相似(只有当我是自己软件的唯一开发人员时)...

我完全在主分支上工作。在不同的“版本”中,我创建了一个悬空分支。

这使我能够通过检查它来回到任何以前的版本。

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

简单易行,足以满足我的需求。

如果我需要对以前的版本进行一些错误修复,我只需要完成该分支并完成它们。

答案 2 :(得分: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

据我所知,这很有效。我会试一试,如果我发现了什么,我会在这里报告。当然,如果你知道的话,我也会对其他方法感兴趣,这些方法不那么黑客。