Git branch structure for Client & Server

2020-07-14 09:22发布

问题:

For one of my CS classes, I and a group are writing an application using a client/server architecture. I was curious what the best-practices would be for organizing the project in a Git repository. What I mean, is whether we should structure the directories like this:

ProjectDir/
    Clients/
        Client1/
            # files...
        Client2/
            # files...
    Server/
        files....

and track everything on the same git branch, or whether we should create separate branches for the clients and the server, like:

on branch Server:

Project/
    Server/
        # files...

on branch Clients:

Project/
    Client1/
        # files...
    Client2/
        # files...

I don't know if it makes much of a difference, but this will be the first project I undertake using git where the team consists of more than a couple people, and I want to make sure the pulls and merges are as simple as possible...

回答1:

I'm not sure what you're background is, but I've heard the same (similar) question asked over and over from people who are coming from central VCS like SVN. The fundamental difference between branches between SVN (centralized) and Git is that Git branches are very light and easy in comparison. After all, in Git, a branch is nothing more than a labeled commit (and the commit points to a commit that points to a commit, down the line until branches converge).

In SVN it's common to host entirely separate projects in the same repository as separate sub-directories. These aren't branches, but in SVN they look indistinguishable from branches (in SVN branches aren't much more than sub-directories). However, you should understand what a branch is. A branch is two near-copies of the same piece of software that are being modified and developed in parallel. If you're unsure if you have a branch, ask yourself if these branches will or could ever converge. If it would never make sense to have the branches converge, they're probably not branches at all.

In you're client-server program, I would suggest that your client & server aren't branches. Rather, they're separate repositories. If you value seeing their history separate, put them in separate repositories. If you want to see their history together, put them in the same repository but under separate directories.

An interesting feature of Git is that, due to it's distributed nature, you could maintain the client and server in separate repositories and then later push them into the same repository as different branches. There would be little difference except being insane to try to understand.



回答2:

I think that you definitely want to keep the client and server libraries on equal footing, but there are two different ways to do this:

  • One repository, two subdirs, as you've indicated. This is certainly the simplest path, and likely sufficient. It sounds like you won't have certain team members working on both components simultaneously, which should keep merges simple, although if you are all being disciplined and segregating your commits through judicious use of feature branches this is almost a non-issue anyways.

  • Two separate repositories, one for the client and one for the server codebase. If you are anticipating sharing a great deal of code between the applications, this becomes more cumbersome, though arguably more correct/scalable for very large components (you would then be using a third repository for your common library code). The use of submodules can help greatly here.

The reason I would advise against separate branches for client and server applications is that they are fundamentally unrelated from a SCM perspective: the history and source code of each piece aren't overlapping or changing as a function of one another, so branching doesn't buy you anything, and causes potential headaches if you have need to comparing or merging the two of them without recent or meaningful common commits.

Either keep them together, because the diffs will show you which component is being affected in each commit anyways, and then you will be able to work with the project as a whole at a higher (source-tree) level, or go all the way and keep them completely separated - repositories in git are lightweight, comparatively speaking, so this is less an indication of a complete break as an enforcing of separate development processes.