1

Pretty new to Git - been using TFS and simple commit/push/branching, so any help appreciated - have spent all day reading and running tests and beginning to think my requirement may not be possible.

There are two of us in the office; Dev 1 doing mostly compiled C# server code, and Dev 2 mostly exclusively web page related work. However, as there are only two of us we do need to cross over fairly regularly, particularly with client Javascript functionality.

We've been doing the "mate I'm working on foo.js" method of source control for client side code, and its worked for a while, but we are doing bigger projects and it's becoming a liability.

Our set up is as below, all on an internal network:

  • Dev 1's machine
  • Dev 2's machine
  • Local Windows Server running IIS that serves the websites under development
  • Shared drive pointing to the IIS root

So, and this is the rapid development cycle I'd like to try and keep, Dev 2 browses to the site under development edits the script / css / html files on the shared drive, hits F5, and the updates are immediately visible. This is a huge benefit for fast working with client side code.

The problems usually occur when Dev 1 needs to make a change to some scripted functionality that happens to require a style change, the same files are opened and saved by both devs, and one of the change sets is lost.

So I'd like to prevent this! However as far as I understand, Git requires the devs to have local repositories so changes can be done without affecting anyone else at all, and then conflicts are merged on commit?

I have set up a test repository on the local server and tried a few scenarios, but as I kind of expected, the scenario where both devs save the same open file is not tracked because neither set of changes has been committed, so as before, only the last set of changes is visible anywhere.

Is there any way of having these type of changes to the same physical file tracked? Or if not, a setup that does track them properly but at least maintains a rapid workflow as close as possible to the above?

Whelkaholism
  • 1,551
  • 3
  • 18
  • 28

3 Answers3

3

Use branches.

Git has a very good branch system. Just create a branch for the work you do - you can even create a branch for every feature you want to implement. And when you "finished" the implementation, merge the branch back to master. So both - and more - developers can work based on a working master version and add there code to the common codebase if it works.

So, the workflow could look like this:

  • Dev1 and Dev2 clone the repo: git clone ....
  • Dev1 works on feature A: git checkout -b A (this creates a lokal branch A)
  • Dev2 works on feature B: git checkout -b B
  • Dev2 finishes his work: git push (on the first call you get a error message about the upstream, the errormessage contains exactly the line you need to create correct upstream, just copy it)
    git checkout master; git pull back to master branch and pull
    git merge B this merges B into master
  • Dev1 need longer for the job and wants to update to newest codebase: git checkout master; git pull; git checkout A; git merge master branch A of Dev1 is now on new codebase.

If you have to work on different features at the same time, there exists also a good system in git. Based from master branch, create a new branch in its own folder - so that both branches are checked out at the same time and there is no need to git checkout <branch> to switch between them:
git worktree add -b <branch> <path>, like git worktree add -b A ../A now you can switch to it trough filesystem (cd ../A) and work on both (or others you created the same way)

If you use github or gitlab, you can protect the master branch and create rules to make merges into it (called pull requests). With appveyor, travis-ci and others there exists services where you can let unittests run and give the pull request free it the unittests do not fail. Based on such a workflow, every developer can work on a running codebase.

About conflicts: With the workflow up there they do not happen as long as both versions didn't modify the same line. But you get a message at the (local) merge, and in the files it is good explained what you can do: (we create a file with a b c in each line, in master we edit b to e, in our branch A we edit b to d, we commit both and merge master into A)

a
<<<<<<< HEAD
d
=======
e
>>>>>>> master
c
codewerfer
  • 320
  • 2
  • 6
  • 2
    @Whelkaholism - this is your answer. Make a branch each. Do work. Merge branch into `master` branch when done. Rinse and repeat. Merge conflicts will occur, but when they do just stick your heads together and take a look at the code snippets and use some sort of diff tool to help you see the conflicts more clearly. GitHub's GUI has a nice one. – IncrediblePony Nov 25 '19 at 09:27
  • I've marked this as the answer because it gets closest to what I want and because it's seeming like what I actually want isn't really possible without having file change notifications set up to commit automatically. – Whelkaholism Nov 26 '19 at 12:07
1

Ideally, you would:

  • isolate the common files in one separate Git repository
  • separate source control (the remote Git repository) from deployment (files copied on IIS root)

That way, each of you can:

  • push to a common remote bare repository: configure it to deny any non-fast-forward push. In case of concurrent pushes, you will be forced to pull first, resolve any conflict locally, then push back: there won't be any change overridden or lost that way.
  • setup a server-side hook in order to (on the server) pull from said bare repository, through a post-receive hook (example here).
  • reference that common repository in your own development repo through a Git submodule.

The goal is to keep separate:

  • project-specific development from common client Javascript functionality.
  • versionning from deployment.
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
0

The problems usually occur when Dev 1 needs to make a change to some scripted functionality that happens to require a style change, the same files are opened and saved by both devs, and one of the change sets is lost.

Is there any way of having these type of changes to the same physical file tracked?

To get this you need some sort of collaborative editor, that's out-of-scope for any existing vcs I know of.

Or if not, a setup that does track them properly but at least maintains a rapid workflow as close as possible to the above?

You need separate files, separate saves (i.e. a vcs) and a workflow that automates as much as possible of the pull-and-push publishing loop.

Since you're not working on the same physical files, before publishing you need to sync your changes with whatever the other guy(s) on your team have published since last you looked. Decide how you want your final history to look; for small-team work like this rebasing onto a shared linear history is often a great place to start, so git config pull.rebase true. Then when you're ready to publish the changes you've saved, commit, pull, push is your cycle; if you and your buddy are making changes even in the same file it'll still apply cleanly in one go so long as the changes aren't immediately-adjacent or overlapping.

jthill
  • 55,082
  • 5
  • 77
  • 137