Working in cloned local repos with multiple branches, best practices?

I am new to working with Github branches so I'm looking for some general 'best practices' guidance on how programmers who are working together in the same remote repo should operate when it comes to pushing changes, when and how this should happen so as to minimize the chance of conflicts and accidental overwrites of others' existing work. So far, our remote repo has just two branches, a 'main' and a 'Features'. Both programmers will start out cloning the remote repo to their local machines. One will be working on the 'backend' code, and the other on the 'frontend', but both will be pushing their work to 'Features'.
If one programmer pushes something, say 'backend' work, to 'Features', and then subsequently the 'frontend' programmer finishes his work and goes to also push it to 'Features', Github will see that the 'Features' branch has since changed ( the 'backend' files that now exist on the remote repo being pushed to now differ from the backend files in the frontend programmer's local cloned repo), and the 'frontend' programmer will be prompted decide how to handle the difference before he is allowed to finish his push, correct? If not 'merge', what would the correct action be, so that the 'frontend' programmer's local unchanged backend files don't overwrite the already-pushed/changed backend files that now exist on the remote repo? Merging 'Features' to main branch As a separate issue, when it comes to merging Features to the main branch (which will function as our 'production' branch), it would be a 'best practice' to only ever do this once both the programmers have finished pushing to 'Features' (meaning they won't be pushing anything else to it). Then, in order to merge Features into main, either one of the programmers, after ensuring they have pulled the most recent finalized version of 'Features' to their local clone, would perform a merge of Features to main, and then push main itself to the remote repo. Is this a correct order of events?
19 Replies
Jochem
Jochem12mo ago
the 'frontend' programmer will be prompted decide how to handle the difference before he is allowed to finish his push, correct?
The frontend developer will be told to pull before they can push, which will attempt to merge any files that both have changed. On failure, git will warn you and tell you to resolve the conflicts (which you do by editing the files and comparing the conflict it marked for you with their incoming code and your outgoing code) you can't push outdated files to a repo without adding --force which you should probably never do unless you really really know what you're doing generally for a team of two, you're fine having a main and a dev branch for most of a project. You can make separate branches for large new features though, so you can work on a new feature in a separate branch and still switch to the dev (or "Feature" as you call it, it's a bit of a confusing name for a development branch) branch to fix active bugs without losing progress on your new feature or having that code be in the way of fixing the bug an alternative is to only work in feature branches, then when you're done merge your code into the development branch, either through a simple git merge or by submitting a pull request for review in your github/gitlab/bitbucket/whatever web interface I'd honestly recommend not using "Features" as a branch name btw. I'm guessing you read about feature branches and are naming it "Features" because of that? Generally, you have a main branch that is protected from accidental commits and can only be merged to using pull requests, then you have a development branch that is the current most advanced version of your software. People check out the development branch, then if they want to work on something, they create what's called a feature branch. A feature branch is literally a branch where you work on a specific new feature. Generally, you'd name them for the ticket in your bug/project tracker to make it easy to keep track. You'd have a ticket with number 37 that's called "Add delete functionality to books", and you'd create a feature branch called 37-add-delete-functionality-to-books. You do your coding while you're in that branch, then merge it with the development branch when you're done and delete the 37-... branch again.
ghostmonkey
ghostmonkey12mo ago
How Jochem described it exactly how I do it as well. It might help to think of branches as temporary / abstract objects instead of permanent / alternative repo endpoints. Rather than always working from the same branch, you can simply open a new branch to make specific changes, Once that task is complete, you can then merge it into the dev or main branch after getting review / sign-off Also, I would say it's unusual to have a combined repo for both front end and back end development. At least from my experience, they have so little overlap, they can just be separated.
Jochem
Jochem12mo ago
that depends on the language. PHP can be very tightly coupled for example sveltekit too
ghostmonkey
ghostmonkey12mo ago
ah yeah, that's a good point, it depends on what framework for sure
thethingisback
thethingisback12mo ago
@Jochem "The frontend developer will be told to pull before they can push, which will attempt to merge any files that both have changed. On failure, git will warn you and tell you to resolve the conflicts (which you do by editing the files and comparing the conflict it marked for you with their incoming code and your outgoing code)" The frontend programmer will be told to pull prior to pushing, even if the files he's pushing (frontend files) wouldn't be conflicting with the remote's changed backend files? He is still required to pull all branch changes first, correct?
Jochem
Jochem12mo ago
yes
thethingisback
thethingisback12mo ago
the only time there will be an attempt to merge anything on a pull is if the same files conflict
Jochem
Jochem12mo ago
and then only if it can't automatically resolve the issue. Say you have a svelte file:
<script>
//hello world
...
</script>
<div>
...
</div>

<style>
...
</style>
<script>
//hello world
...
</script>
<div>
...
</div>

<style>
...
</style>
If the frontend dev edited stuff in the style tag, and the backend dev edited something in the javascript at the top, git will be able to merge the file automatically only if you edited the same bits of code, will you get a warning to merge manually
thethingisback
thethingisback12mo ago
gotcha @Jochem "Generally, you have a main branch that is protected from accidental commits and can only be merged to using pull requests, then you have a development branch that is the current most advanced version of your software. People check out the development branch, then if they want to work on something, they create what's called a feature branch." This is probably the model we'll use then. "Dev" will be available for fixing any bugs, enabling us to separately continue making progress with whatever feature is being worked on. So say one person is working in 'Dev' fixing a bug while the other person is in "FeatureX" branch working on a feature. The person working on the bug would push his 'fixed' version to the 'Dev' branch.. and then when the 'FeatureX' programmer is ready to push his/her work, they'll be prompted to first pull (and/or merge) the 'fixed changes' from 'dev' before they can push to 'dev'. And then they'll be a single bug-fixed /featureX-implemented version living in 'dev'. This is how this would work? The only other question I'd had with this model is when to consider something a 'feature'.. warranting creating a dedicated 'featureX' branch for it, versus just 'general building', wherein I'd assume we'd just stay in the 'dev' branch?
Jochem
Jochem12mo ago
well, no, the branches are separate. You'd pull the latest version of dev when you're done with featurex, then you merge featurex into dev, retest your feature, then push dev back to the server you can also pull changes from dev into featurex if dev is updated while you're working on featurex, if necessary
The only other question I'd had with this model is when to consider something a 'feature'.. warranting creating a dedicated 'featureX' branch for it, versus just 'general building', wherein I'd assume we'd just stay in the 'dev' branch?
a lot of places will only do work based on tickets or stories or whatever you want to call them, and then only work in feature branches. It's not completely necessary on a team of two though I'd honestly again recommend reading the git book I linked a while ago (it's free and kept up to date), and maybe even following a git course. This kind of thing is usually set up by a senior dev or a team who has/have experience with git
thethingisback
thethingisback12mo ago
"well, no, the branches are separate. You'd pull the latest version of dev when you're done with featurex, then you merge featurex into dev, retest your feature, then push dev back to the server" So say one person's working on a bug in the 'dev' branch, the other person is in the other branch, featurex branch, working on a feature. Whoever is finished first, it doesn't matter, would pull from 'dev' first, assuming there were changes to dev, then push their work to 'dev'. Either way, whether the 'bug fix' changes were pushed to 'dev' first or the 'featurex' changes were pushed to 'dev' first.. in either case, when the other person goes to push their changes, they'll be required to pull those changes and reconcile any differences, before they can push their changes. Is that correct?
Jochem
Jochem12mo ago
the verbiage isn't quite correct, but the process is you don't pull changes to a different branch, that's called a merge
thethingisback
thethingisback12mo ago
"they'll be required to pull those changes" here i was meaning to pull from dev pull anything that's been changed in dev, down to their local repo I'll go over the book too, but this has been very helpful, thank you again @Jochem & @ghostmonkey !
Jochem
Jochem12mo ago
just ensure you know what you're doing before you start messing with this in production, and make doubly sure you have backups of everything you can very easily delete a lot of work if you mess things up, so set up automated backups of your repo to run every day and if you ever do something you're unsure about, run another manual one first
ghostmonkey
ghostmonkey12mo ago
my daily steps are generally: I first do a git status and make sure my local is up to date or fetch the origin if its not. Then I checkout the local branch I will work on (either the ticket name/number, or I just use my name if I am doing general stuff). Then when I am finished or at the end of the day, I commit my changes and push the local branch back to the origin. If it's a specific fix from a ticket, i merge it and done. If it's just updates I am doing under my name, I keep using that branch for a week or so, or until I have made major changes, and then merge it. It's pretty straight forward once you get used to it, and like Jochem said, just have your boss or a senior make sure you are doing it right the first few times until you are comfortable.
thethingisback
thethingisback12mo ago
@ghostmonkey "Rather than always working from the same branch, you can simply open a new branch to make specific changes, Once that task is complete, you can then merge it into the dev or main branch after getting review / sign-off" The developer would make a local clone of the existing remote repo, getting its 'main' and 'development' branches in the process. Then they create a local 'feature' branch, ex; a 'featureX' branch, copy-committing all of their local 'development' branch's files into the new local 'featureX' branch in the process. And then while they develop the feature, are they just directly pushing their 'featureX' branch to the remote repo? And then when they finally need to merge their completed featureX branch to the 'development' branch, how is that happening? It seems like at that point, instead of push directly to remote repo's 'featureX' branch, they'd first merge their local featureX branch with their local 'development' branch, and then push their local 'development' branch to the remote repo. Is that correct?
ghostmonkey
ghostmonkey12mo ago
to clarify a bit more on my specific use case (there are many ways to do this and it depends mostly on what the team you are working with has setup, so follow their guidelines first and foremost): 1. The org I am working with has separate repos for the live site, the dev backend, the dev front end, and the documentation 2. I generally only work with the Front End devolopment repo which only has that main branch 3. We have a private team board in the Github Projects section where all the requested changes, tickets, fixes etc are listed and assigned to either BE, FE, or Doc 4. So, when I go into the team board, I find the next backlog issue that is assigned to FE, and then I know what I need to work on 5. on my local dev, i pull the FE origin to make sure its up to date, then i checkout a branch off that using the title of the team board issue 6. When I have fixed it, I push that branch name up to the repo, so that the admin can see that the specific issue has been fixed 7. Then they will merge it back to the FE main, and close the team board issue 8. but, if I am working on something that isn't a fix, say an updated UI enhancement or new component etc, then instead, I just make a branch with my name which I then push up to the origin and the admins know they don't need to mess with it but they can still see what I am working on before it's merged
thethingisback
thethingisback12mo ago
@ghostmonkey Suppose a person's working on a feature. I'm tempted to say they should avoid pushing their local feature branch to the remote repo at all, up until the point where it's pretty much complete. The idea being that they can test their feature and merge it to the latest pulled version of the 'dev' branch all locally. Operating that way, I just have a question. They get to work, and before they start working on their feature again, they perform a 'git pull' from the remote 'dev' branch down to their local 'dev' branch. When they initially created their local 'feature' branch, it was based off of a now-older version of the 'dev' branch. So, in order to make sure their 'feature' branch is being built in a way that is always compatible with the latest-pulled 'dev' branch, does that mean that every time they update their local 'dev' branch, they would also need to merge that latest pulled 'dev' branch to their local feature branch as well? So that while they build the feature, they know its based off of the latest version of the 'dev' branch? I'm trying to iron out the micro of how a person's local 'feature' branch would eventually become merged to the remote repo's 'dev' branch
ghostmonkey
ghostmonkey12mo ago
I think you'll just need to do it for a bit to really get a feel for it. But, also read the book linked by Jochem, or watch a few youtube videos. You are still thinking of branches as these freestanding separate entities, but really they are just duplicates of the main, where you are making changes that won't be implemented until they are merged back into main when you do git status, it will tell you if your branch is up to date. Also on github, you can click the list of branches, and one of the things it will tell you is how many commits behind and how many commits ahead of main you are (commits behind are changes to main since you last synced, commits ahead are how many changes you have made that haven't been merged yet) if you push your branch to the repo, you will have an option to 'compare and pull requests' and that begins the process where you can ensure that your work is in sync with the main repo, and that there are no conflicts. It will check it all automatically for you and alert you to any issues, and if none exist, you can merge the pull request and your branch is gone and merged wtih main
Want results from more Discord servers?
Add your server