Maintaining multiple branches of the same base project in VS

I've looked around the site but I couldn't find an answer that covers mine entirely, so please excuse me in advance if I missed it.

I inherited a VB.NET project that didn't have source control (it started as a pet project of a long-gone dev and nobody ever bothered after that to put it in), and by a friend's suggestion I thought about using Git for source control.

The project is a niche product that is customized and sold according to the customer's specs, so that brings the problem that even if 95% of the code is the same for all the customers, sometimes up to 10% of the code is changed and tailored for each customer, by changing or adding lines to existing functions, sometimes adding whole blocks of code, but there's no commonality in the changes between different customers (a function changed in one might not be changed in another).

To complicate things further, due to maintenance contracts, updates made to the baseline app have to be replicated in the customer's branches should they want them, and sometimes changes we make for a specific customer are good enough that we want to put them in the baseline app and replicate them to the other customers, BUT keeping the customizations for each customer!

So with my little knowledge of Git, I thought it would be like:

          (customer 1)
         C1-----
(main)  /
A------B------D
        
          (customer 2)
         C2-----
        
          (customer 3)      
         C3-----

...but I can't see how it's going to work after that:

  • Can I merge SOME changes from the customer's branches into the main trunk WITHOUT merging others that are only useful for that customer?
  • Can I merge SOME changes from the main trunk into each customer's branches WITHOUT losing the customizations in those branches?
  • Can I "mark" specific lines of code so they are not merged/committed?
  • Three or more devs will be working in this, each in his own machine but pushing changes to the company's repository for synchronization. What are the implications for this process?
  • Right now, every customer has a separate folder and separate project files with all their source code. How would be the import process to put those folders them into Git?
  • All of this must be done with Visual Studio, with Gitextensions and the Git Source provider for VS. Is it supported, or it has to be done with the console?
  • Thanks and sorry again if it overlaps with another answer.


    I'm relatively new to git and normally use PoshGit for all my operations, so while I may not be able to help you with everything, I hope I can help with some things:

  • Can I merge SOME changes from the customer's branches into the main trunk WITHOUT merging others that are only useful for that customer?
  • Can I merge SOME changes from the main trunk into each customer's branches WITHOUT losing the customizations in those branches?
  • From what I understand, both of these operations can be achieved by using git cherry pick , which allows you to pick a particular commit from one branch, and add it to another without merging the branches together.

    For example, assuming you want to add a change made to customer1's repository, to customer2:

    First you get the hash ID of the commit from customer 1 that you want to insert into customer2

    git checkout customer1Branch
    git log 
    
    commit 2e8c40025939e8cf41dec70f213da75aa462184b
    Author: xxxxxxx
    Date: xxxxxx
    
    This made a change that you want...
    

    You then copy the first few characters of the hash you want to cherry pick , change to customer 2's branch and cherry pick it into the branch.

    git checkout customer2Branch
    git cherry-pick 2e8c40025939e8c
    

    Now, if you do a git log , you'll see your cherry pick at the top. A similar tutorial can be found here (http://nathanhoad.net/how-to-cherry-pick-changes-with-git)

  • Can I "mark" specific lines of code so they are not merged/committed?
  • You may find help from a similar question was asked and answered here:

    Commit only part of a file in Git

  • Three or more devs will be working in this, each in his own machine but pushing changes to the company's repository for synchronization. What are the implications for this process?
  • Since GIT is a fully Distributed VCS, each dev on your team will effectively have a full clone of the central repo on his own machine (complete with full history of that repo.) This means that log history queries and other requests (such as finding out who did what) don't need to go through your central server, but can be done privately and offline by each dev.

    Similarly, the changes that each dev makes will become available to all of you (for example, all new branches will be available), but it can sometimes be frustrating to be working on the same features if you're not quite used to git.

    As always its a good idea to commit early and often, this will decrease the tension you're likely to face when changes clash. you should also set some structure to when pushes are done, especially if you rely on each other's work to continue.

    Another idea you may want to try is having one person in charge of the repo and having him merge changes and patches to help coordinate your efforts.

  • Right now, every customer has a separate folder and separate project files with all their source code. How would be the import process to put those folders them into Git?
  • EDIT

    Thanks for clarifying what you meant by this question. You could expand on a similar approach adapted from the answer given here: How do you create a remote Git branch?

    Create a new mainline branch for your BASE project and push it to your remote repository.

    cd baseProjectDirectory # navigate to your main project directory
    git init # git initialize the dir
    git add . # recursively add all files in directory to git repo
    git remote add <remote-branch-name> <remote-url> # Add the url to your remote directory to your git repo
    git commit -m "Initial commit of base project"
    git push <remote-branch-name> <local-branch-name>
    

    This will establish your Baseline project on a remote repository called remote-branch-name under a branch called local-branch-name .

    You can then navigate to your other projects and repeat these steps putting your repositories under different branches on the same remote, by using new local branch names, ie instead of using the local-branch-name when creating a branch, just use a new branch name, such as git checkout -b new-local-branch-name

    so if, for example your base project push (the last line of code) was:

    git push clientproject base
    

    Where "clientproject" is the name of your remote, and "base" is the name of your local branch, you can just change the line to:

    git checkout -b client1 # Creates new branch named client1
    git branch -d base # Deletes base branch
    git push clientproject client1
    

    Note that while it's not strictly necessary to delete the "base" branch before continuing, it does keep your repository cleaner and is thus considered good practice. Don't worry about losing anything though, your entire git history from base will be copied to client1 on checkout.

    Also note: Since your situation requires you to do this from different directories, you'll probably be deleting a branch named "master" and not "base".

    Pushing like this will keep client1 on the "clientproject" remote, but will place the project under on a new branch called client1, complete with its own history.

    The same steps can be used for the rest of the projects. If I've lost you anywhere along the way, I suggest reading the above link (it's much more concise than I am).

  • All of this must be done with Visual Studio, with Gitextensions and the Git Source provider for VS. Is it supported, or it has to be done with the console?
  • I haven't yet used VS with Git, but I assume most if not all these operations would be supported since they are native git commands.

    Hope this helps.

    链接地址: http://www.djcxy.com/p/4194.html

    上一篇: 我怎样才能保存一个特定的文件?

    下一篇: 在VS中维护同一个基础项目的多个分支