Background
I've recently become the technical lead/senior developer for a small R&D/data science team. I've got a decent amount of non-lead experience in bigger development teams, but I've not got any formal education in project or team management.
There are a few experienced programmers on the team, but the others haven't had much experience working on bigger projects. They currently use Git to manage their codebase albeit in a rather unconventional way: So far, people have been effectively "branching" by copying the entire codebase for a project as a new repository. They effectively "tag" the repository with a descriptive name and then largely don't touch it once they "release" the tagged code unless some critical bug is discovered.
For example, here is how this would look for the products named arthur and lancelot:
small_companys_code
├── arthur (this is the "basic" bleeding edge "branch" of project "arthur")
├── arthur-Jan2015 (this is a "tag" for a stable release in Jan 2015)
├── arthur-multilang (this is a "development branch" for the new feature "multilang")
├── arthur-multilang-Mar2016 (this is a "tag" for a release in Mar 2016 with a new feature "multilang", maybe not necessarily merged into the repo "arthur")
├── arthur-fred (these are the personal changes of the former employee Fred. No one remembers exactly what changes this has)
├── lancelot (this is the "basic" bleeding edge "branch" of project "lancelot")
├── lancelot-Feb2018 (this is a "tag" for a stable release in Feb 2018)
├── lancelot-Feb2018-spanish (this is almost exactly the same as "lancelot-Feb2018" but was quickly changed to support Spanish for demonstrating)
This works well enough for the people who've stayed long enough to know where everything is. However, for new people (myself included), this is likely very daunting.
Goal
One of my official responsibilities is to "clean this up" and in doing so primarily ensure that there is always a working, releasable version of each project (arthur and lancelot above). The exact workflow is undecided at the moment; My immediate task is to re-organize the code primarily so that there is always a releasable "latest" stable version of the code which can be easily deployed and run even if it doesn't necessarily have all the features developed for other versions (i.e. experimental or features planned for the future):
small_companys_code
├── arthur (repo for project "arthur")
| ├── master (branch for project "arthur" including only tested features which will definitely be included in later versions of product)
| | ├── Jan2015 (release tag)
| | ├── multilang (branch for new feature)
| | | ├── Mar2016 (release tag for demo'ed version of feature "multilang")
| | ├── fred (orphaned branch to eventually be merged/removed)
├── lancelot (repo for project "lancelot")
| ├── master (branch for project "lancelot" including only tested features which will definitely be included in later versions of product)
| | ├── Feb2018 (release tag)
| | ├── spanish (branch for quickly-hacked "feature", possibly to be developed or merged but maybe just removed)
| | | ├── Feb2018 (release tag for one-off demo)
How can I approach this task? Since the repositories were essentially copied in most cases, I can't rely on searching through the Git commit logs. I can of course look at the actual real-world dates for the changes and create a chronological ordering of the different repositories, but I'm not sure how I can use this information to create a proper Git workflow like the one shown above.