DEV Community

Cover image for How do you use git between devices?

How do you use git between devices?

Doug Bridgens on May 07, 2024

If I'm working on a feature, on a branch, I struggle to do that while working 'remotely'. When I work remotely I don't mean from the kitchen table...
Collapse
 
benr77 profile image
Ben

You could also practice continuous integration with yourself (i.e. even though there is no team).

Working in very small steps, the code is ALWAYS in a releasable state, and you only commit to main. If stuff needs to be hidden, use feature flags (a simple implementation can just be a config setting in the code - no need for a fully fledged feature flag product).

Collapse
 
daunderworks profile image
Doug Bridgens

Yeah, I do try to do this. But life sometimes gets in the way, more so as a solo dev on projects without a boss 😃

I've found that no matter how small the intention, sometimes I still reach for a checkpoint commit.

Collapse
 
benr77 profile image
Ben

Sure, but what I'm saying is the checkpoint commit doesn't have to be a bad thing to be avoided.

As long as the code compiles/runs, just commit it as though it was a normal part of your workflow. Don't call it a "checkpoint", just describe what and why you've done it like any other commit.

If you are working in small steps anyway, this shouldn't be much different from any of your other commits.

Basically if the code is good enough to keep, it's good enough to make it a "proper" commit, and if it's not good enough to keep you should just delete it and start over in your next coding session. If this feels like you are wasting work, it's because you are working in too large a step.

Also, if your commit history is really bothering you, remember about Git's interactive rebase feature - this allows you to do a lot of tidying afterwards if you feel the need.

Thread Thread
 
daunderworks profile image
Doug Bridgens

The checkpoint isn't bad code, it's just unfinished. And I want to finish it on another device.

You raise a good view though, which maybe modifies the question. If I'm already doing reasonably continuous integration in practice, is it possible to go one level more in granularity?

If I am working on my smallest chunk of change , something that's a single commit sized, is it possible to do that across two devices?

I've been bound by the git way of working for nearly twenty years. The concept that the commit is smallest part of the system, and indivisible. And you must sit still until it's completed.

But how we work has changed. I stopped being office based ten years ago, and stopped 9-5 hours over five years ago. In my mind is something like a cross between git and Google Docs.

Hmm.. just had a thought about creating a public VM with a file sync process. Maybe when I am leaving my desktop I can sync branch changes, and do the same on my laptop. I might try and see if that would work in practice.

thanks for your feedback, it's making me think 👍

Thread Thread
 
benr77 profile image
Ben

You could just spin up a NextCloud droplet (check it out on Digital Ocean Marketplace).

But I still think you are over-complicating things, and just need to use smaller commits. If you read Kent Beck's description of the TDD process you realise how tiny a commit can or should be.

Thread Thread
 
daunderworks profile image
Doug Bridgens

Ah, I didn't know about NextCloud. Interesting.

Yes, I understand development methodologies. And I also break them when I need to. I'm doing systems development, some data generation, infrastructure code, app development, documentation, etc, all in parallel. I'm building an app solo, which often (always 😂) means non-linear work.

I really do get what you're saying. But the position I find myself in is juggling five repo's concurrently, to develop features and deploy those features and document those features. It would be great to have a team on each stream of work, focused exclusively on that code and feature delivery.

Collapse
 
ridays2001 profile image
Riday

If you're working on something and have to switch devices, you can create a new branch and add a WIP commit. Then, when you are done, you can use git merge --squash <branch-name> to squash the WIP commits as one single commit into the main branch.

Zsh has this helpful alias for git - gwip that automatically adds a WIP commit. You can then use gunwip to undo the WIP commit. And then you can also do a force push to erase the WIP commit from GitHub history.

I encountered a situation similar to yours when I used a dual boot setup. Sometimes I shared projects between both OS on the same laptop. I used to create a new branch, push a checkpoint commit, switch OS, pull, undo the checkpoint or merge with squash if done. Sometimes, I just pushed the checkpoint commits to the main branch, then I used undo commit and force push to erase history.

Collapse
 
daunderworks profile image
Doug Bridgens

Ah, that's interesting. Nice, and uncontroversial 😃

Yes, dual boot would bring up the same challenge.

I'm going to give this a go, as it's fairly simple. 👍

thanks

Collapse
 
daunderworks profile image
Doug Bridgens • Edited

Now into the rabbit hole... 😂

I've just discovered that GitHub lets you modify the merge commit message. You can set it to the PR title (Settings>General>Pull Requests), which is a big help.

This makes the git log more readable:

$ git log --all --oneline --graph               
*   9669f21 (HEAD -> main, origin/main, origin/HEAD) Adds animal feature (#3)
|\  
| * 716f790 (origin/feature3, feature3) adds animal business logic
| * f044934 adds animal datastore
|/  
*   3ac9909 Adds person feature (#2)
|\  
| * cbf63f0 (origin/feature2, feature2) adds person business logic
| * c6429c1 checkpoint
| * 9d364d1 adds person datastore
|/  
*   ea50fad initial main function (#1)
|\  
| * 4bd88ab (origin/feature1, feature1) initial main function
|/  
* 9364e87 Initial commit
Enter fullscreen mode Exit fullscreen mode

Here I've done a soft reset on feature3.

And a summary is simple (with the merge commits set to PR title):

$ git log --first-parent --oneline
* 9669f21 (HEAD -> main, origin/main, origin/HEAD) Adds animal feature (#3)
* 3ac9909 Adds person feature (#2)
* ea50fad initial main function (#1)
* 9364e87 Initial commit
Enter fullscreen mode Exit fullscreen mode

Just need to figure out an alias function and where to apply it. But, getting the checkpoint commit hash, and then doing a soft reset to the preceding commit.

$ git cherry -v main
+ f044934704fff123ae2b3e9a41e8c79965a41a37 adds animal datastore
+ 670f395cfe6010e8fb9213485b930ae7ad57256d checkpoint

$ git reset --soft f044934704fff123ae2b3e9a41e8c79965a41a37

$ git commit -a -m 'adds animal business logic'
Enter fullscreen mode Exit fullscreen mode
Collapse
 
phlash profile image
Phil Ashby

Two things I've done in the past in this situation (neither of which actually use git, please feel free to shout cursed!):

  • File sync between devices, so I have the exact same state everywhere.. after all git fetch/push are effectively this to a shared repo, but I also have stash, modified things....

  • Remote dev system, that I RDP/ssh/vnc/etc. into, usually for me this is an Azure VM. Depends on network staying up which might be challenging on trains.

Collapse
 
daunderworks profile image
Doug Bridgens • Edited

Ha, vnc. Do you remember when Citrix (desktop) arrived on the scene? I think this may be tricky (for me), for the connection issues you mention. On the other hand, things like Google Docs (or any other mainstream note/doc sharing) work fine as part of a fairly random work day. It's interesting that nothing like this sync (as opposed to vnc-like) exists.

Yes, I'm thinking a simple file sync may be useful. Given that I am leaving my desk (iMac) and knowingly going on the road to work on my laptop. So $ sync_my_wip would be easy.

I've been toying with @ridays2001 suggestion. It looks pretty neat, and easy.

Explicitly branching off my feature branch to create a checkpoint/wip branch, where I don't care about commit messages:

*   5f5abbd (HEAD -> main) Adds robot feature.
|\  
| *   e7d3b17 (feature4) Adds robot business logic
| |\  
| | * def0ab3 (wip) my second checkpoint
| | * 1b42f7e my first checkpoint
| |/  
| * 68b0ecb adds robot datastore
|/  
*   9669f21 (origin/main, origin/HEAD) Adds animal feature (#3)
|\  
| * 716f790 (origin/feature3, feature3) adds animal business logic
| * f044934 adds animal datastore
|/  
*   3ac9909 Adds person feature (#2)
|\  
| * cbf63f0 (origin/feature2, feature2) adds person business logic
| * c6429c1 checkpoint
| * 9d364d1 adds person datastore
|/  
*   ea50fad initial main function (#1)
|\  
| * 4bd88ab (origin/feature1, feature1) initial main function
|/  
* 9364e87 Initial commit
Enter fullscreen mode Exit fullscreen mode

And then the same graph when I'd squash the merge of my wip branch back into my feature branch, where I get a commit message to say what happened:

*   5f5abbd (HEAD -> main) Adds robot feature.
|\  
| * e7d3b17 (feature4) Adds robot business logic
| * 68b0ecb adds robot datastore
|/  
*   9669f21 (origin/main, origin/HEAD) Adds animal feature (#3)
|\  
| * 716f790 (origin/feature3, feature3) adds animal business logic
| * f044934 adds animal datastore
|/  
*   3ac9909 Adds person feature (#2)
|\  
| * cbf63f0 (origin/feature2, feature2) adds person business logic
| * c6429c1 checkpoint
| * 9d364d1 adds person datastore
|/  
*   ea50fad initial main function (#1)
|\  
| * 4bd88ab (origin/feature1, feature1) initial main function
|/  
* 9364e87 Initial commit
Enter fullscreen mode Exit fullscreen mode

I really think this is a cool workflow/solution. And easy with some shell alias functions.

The filesync is what I'll try if this doesn't work out. 👍

Collapse
 
mrlinxed profile image
Mr. Linxed

You could use feature branches and squash merge them when they are done. Then in your main/master branch, you'll only have one meaningful commit.

Collapse
 
daunderworks profile image
Doug Bridgens

I'm old enough to believe squashing commits is bad, because you lose that history. Therefore it's pointless to write commit messages at all. Although I understand that this is not the modern view 😃

The way we old-timers see a summary view, with git log and --first-parent:

$ git log --first-parent --oneline
* 9669f21 (HEAD -> main, origin/main, origin/HEAD) Adds animal feature (#3)
* 3ac9909 Adds person feature (#2)
* ea50fad initial main function (#1)
* 9364e87 Initial commit
Enter fullscreen mode Exit fullscreen mode

This means we do the squashing just on the view, rather than throw away the meaningful commit information.