<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>OneDrive on monkshark.dev</title><link>https://monkshark.github.io/tags/onedrive/</link><description>Recent content in OneDrive on monkshark.dev</description><generator>Hugo -- gohugo.io</generator><language>ko</language><lastBuildDate>Wed, 15 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://monkshark.github.io/tags/onedrive/index.xml" rel="self" type="application/rss+xml"/><item><title>#11 - 작업이 전부 날아갔다</title><link>https://monkshark.github.io/p/lost-changes/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><guid>https://monkshark.github.io/p/lost-changes/</guid><description>&lt;h2 id="날아갔다"&gt;&lt;a href="#%eb%82%a0%ec%95%84%ea%b0%94%eb%8b%a4" class="header-anchor"&gt;&lt;/a&gt;날아갔다
&lt;/h2&gt;&lt;p&gt;2026년 4월 3일. 전날부터 UI 전면 개편 작업을 하고 있었다. 앱의 거의 모든 화면을 건드리는 큰 작업이었다. 게시판 레이아웃을 바꾸고, 채팅에 읽음 표시를 넣고, 개인정보 동의 화면을 만들고, 교사용 시간표를 추가하고, Cloud Functions로 푸시 알림을 연결하고 — 한 마디로 앱 전체를 뜯어고치는 중이었다.&lt;/p&gt;
&lt;p&gt;그리고 한순간에 전부 사라졌다.&lt;/p&gt;
&lt;h2 id="배경-onedrive-폴더"&gt;&lt;a href="#%eb%b0%b0%ea%b2%bd-onedrive-%ed%8f%b4%eb%8d%94" class="header-anchor"&gt;&lt;/a&gt;배경: OneDrive 폴더
&lt;/h2&gt;&lt;p&gt;프로젝트 폴더가 OneDrive 동기화 경로 안에 있었다. 처음부터 의도한 건 아니고, 바탕화면이 OneDrive에 연결되어 있었는데 거기서 프로젝트를 만든 거다.&lt;/p&gt;
&lt;p&gt;평소에는 별 문제가 없었다. 파일을 수정하면 OneDrive가 알아서 클라우드에 올리고, 혹시 모를 상황에 백업도 되니까 오히려 편하다고 생각했다. 실제로 한동안 아무 탈 없이 잘 돌아갔다.&lt;/p&gt;
&lt;p&gt;문제는 이 구조가 Flutter 프로젝트와 근본적으로 맞지 않는다는 점이다. &lt;code&gt;build/&lt;/code&gt;, &lt;code&gt;.dart_tool/&lt;/code&gt;, &lt;code&gt;node_modules/&lt;/code&gt; 같은 폴더는 빌드할 때마다 수천 개의 파일을 생성하고 삭제한다. OneDrive는 이 파일들을 전부 동기화하려고 한다. 파일 잠금이 걸리고, 동기화 충돌이 나고, 결국 빌드 자체가 안 되는 상황이 온다.&lt;/p&gt;
&lt;h2 id="터진-순간"&gt;&lt;a href="#%ed%84%b0%ec%a7%84-%ec%88%9c%ea%b0%84" class="header-anchor"&gt;&lt;/a&gt;터진 순간
&lt;/h2&gt;&lt;p&gt;빌드가 안 됐다. 정확한 에러는 기억 안 나지만, 캐시나 빌드 파일이 꼬인 전형적인 증상이었다. &lt;code&gt;flutter clean&lt;/code&gt;을 해야 하는 상황.&lt;/p&gt;
&lt;p&gt;그런데 OneDrive 동기화가 걸려 있으면 clean이 제대로 안 된다. 파일을 지워도 OneDrive가 클라우드에서 다시 복원하거나, 동기화 중인 파일이라 삭제가 안 되거나, 잠금이 걸려서 빌드 디렉토리를 못 지운다.&lt;/p&gt;
&lt;p&gt;그래서 OneDrive 백업 설정을 껐다. &amp;ldquo;이 폴더 동기화 중지.&amp;rdquo; 이러면 깔끔하게 clean build를 할 수 있을 거라고 생각했다.&lt;/p&gt;
&lt;p&gt;OneDrive는 동기화를 중지하면서 로컬 파일을 클라우드에 마지막으로 저장된 상태로 되돌렸다. 마지막 커밋 시점. 커밋하지 않은 모든 변경사항 — UI 전면 개편의 모든 작업이 증발했다.&lt;/p&gt;
&lt;p&gt;터미널에서 &lt;code&gt;git status&lt;/code&gt;를 쳤을 때 &lt;code&gt;nothing to commit, working tree clean&lt;/code&gt;이 뜬 그 순간의 기분은 설명하기 어렵다. 분명 수십 개 파일을 수정했는데, clean이라니.&lt;/p&gt;
&lt;h2 id="날아간-것들"&gt;&lt;a href="#%eb%82%a0%ec%95%84%ea%b0%84-%ea%b2%83%eb%93%a4" class="header-anchor"&gt;&lt;/a&gt;날아간 것들
&lt;/h2&gt;&lt;p&gt;커밋 메시지에 남긴 복구 목록이다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Restored (lost from git reset --hard):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- Category chips Wrap, post action sheet, bookmark, chat icon
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- Chat: leave, message delete, read receipts, system messages, limit(30)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- Privacy consent checkbox, privacy policy in-app screen
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- Home refresh (WidgetsBindingObserver, RefreshIndicator), board→recent order
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- Crashlytics + crash log to Firestore
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- Onboarding→login flow, HomeScreen tab refresh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- My activity 3 tabs (posts/comments/bookmarks)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- Teacher timetable, today highlight, font 12px
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- Cloud Functions: chat push, reply notifications
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- Firestore rules: crash_logs, field-level post update
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;실제로는 &lt;code&gt;git reset --hard&lt;/code&gt;를 한 게 아니라 OneDrive가 파일을 되돌린 건데, 효과는 같았기에 커밋 메시지에 그렇게 적었다. 핵심은 커밋하지 않은 작업이 전부 사라졌다는 것이다.&lt;/p&gt;
&lt;p&gt;하나씩 보면:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;채팅 시스템 대규모 개선.&lt;/strong&gt; 읽음 표시, 메시지 삭제, 나가기 기능, 시스템 메시지, 메시지 30개 제한. 채팅 화면만 344줄이 바뀌었다. 이건 단순 UI가 아니라 Firestore 쿼리, Cloud Functions, 클라이언트 로직이 엮인 기능이다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;개인정보 처리방침.&lt;/strong&gt; 회원가입 시 동의 체크박스, 인앱 개인정보처리방침 화면. 법적으로 필요한 기능이라 빠뜨릴 수 없었다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;내 활동 3탭.&lt;/strong&gt; 내 글, 내 댓글, 북마크를 탭으로 나눠 보여주는 화면. 각 탭이 별도 Firestore 쿼리를 가지고 있었다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;교사 시간표.&lt;/strong&gt; 일반 학생 시간표와 구조가 다르다. 교사는 여러 학급에서 수업하니까 학년/반 선택이 필요하고, 멀티 클래스 선택을 지원해야 했다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cloud Functions.&lt;/strong&gt; 채팅 푸시 알림, 댓글 답글 알림. 클라이언트가 아니라 서버 사이드 코드라 별도로 테스트하고 배포한 거였다.&lt;/p&gt;
&lt;p&gt;전부 커밋 전이었다. Git에 흔적이 없다.&lt;/p&gt;
&lt;h2 id="복구-6시간"&gt;&lt;a href="#%eb%b3%b5%ea%b5%ac-6%ec%8b%9c%ea%b0%84" class="header-anchor"&gt;&lt;/a&gt;복구: 6시간
&lt;/h2&gt;&lt;p&gt;같은 날 오전 6시 반에 복구 작업을 시작해서, 12:26에 복구 커밋을 찍었다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;18 files changed, 1,432 insertions(+), 314 deletions(-)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;6시간 만에 18개 파일, 1,432줄을 다시 쳤다. 거기에 원래 계획에 없던 피드백 시스템(버그 신고 + 학생회 건의함)까지 새로 추가했다.&lt;/p&gt;
&lt;p&gt;한 번 만들어본 코드를 다시 치는 건 확실히 빠르다. &amp;ldquo;이 화면에 이 위젯이 필요하고, 이 Firestore 쿼리를 써야 하고, 이 Cloud Function이 이 트리거로 동작한다&amp;rdquo; — 설계를 처음부터 고민할 필요가 없으니까. 머릿속에 완성된 그림이 있고, 타이핑만 하면 된다.&lt;/p&gt;
&lt;p&gt;하지만 원본과 같은 코드는 아니다. 처음 만들 때는 시행착오를 거친다. 이 변수명이 맞나, 이 조건 분기가 맞나, 이 에러 핸들링은 충분한가 — 그 과정에서 다듬어진 디테일들이 있다. 복구할 때는 &amp;ldquo;대충 이랬다&amp;quot;로 넘어간다. 복구한 코드는 기능은 같지만, 처음 코드가 가졌던 미세한 개선들은 빠져 있다.&lt;/p&gt;
&lt;p&gt;그래도 전부 잃는 것보단 훨씬 낫다.&lt;/p&gt;
&lt;h2 id="이후-바꾼-것들"&gt;&lt;a href="#%ec%9d%b4%ed%9b%84-%eb%b0%94%ea%be%bc-%ea%b2%83%eb%93%a4" class="header-anchor"&gt;&lt;/a&gt;이후 바꾼 것들
&lt;/h2&gt;&lt;h3 id="프로젝트-폴더-이동"&gt;&lt;a href="#%ed%94%84%eb%a1%9c%ec%a0%9d%ed%8a%b8-%ed%8f%b4%eb%8d%94-%ec%9d%b4%eb%8f%99" class="header-anchor"&gt;&lt;/a&gt;프로젝트 폴더 이동
&lt;/h3&gt;&lt;p&gt;OneDrive 동기화 경로 밖으로 프로젝트를 옮겼다. &lt;code&gt;C:\Users\Desktop\&lt;/code&gt; 아래에 두되, OneDrive 동기화 대상에서 제외했다. 백업은 Git이 하면 된다. 클라우드 동기화 서비스는 코드 저장소가 아니다.&lt;/p&gt;
&lt;h3 id="커밋-습관"&gt;&lt;a href="#%ec%bb%a4%eb%b0%8b-%ec%8a%b5%ea%b4%80" class="header-anchor"&gt;&lt;/a&gt;커밋 습관
&lt;/h3&gt;&lt;p&gt;&amp;ldquo;큰 작업 끝나면 한 번에 커밋하자&amp;rdquo; → &amp;ldquo;작은 단위로 자주 커밋하자&amp;quot;로 바꿨다.&lt;/p&gt;
&lt;p&gt;이전에는 여러 기능을 한꺼번에 만들고 한 커밋에 몰아넣었다. 커밋 메시지에 &amp;ldquo;Major update: board, notifications, admin web, UI overhaul&amp;rdquo; 같은 게 나오는 이유다. 깔끔한 커밋 히스토리보다 작업 흐름을 끊지 않는 게 더 중요하다고 생각했다.&lt;/p&gt;
&lt;p&gt;사건 이후에는 기능 하나가 완성되면 바로 커밋한다. 완벽하지 않아도. 커밋 메시지가 좀 지저분해져도. 커밋하지 않은 코드는 존재하지 않는 코드다.&lt;/p&gt;
&lt;h3 id="gitignore"&gt;&lt;a href="#gitignore" class="header-anchor"&gt;&lt;/a&gt;.gitignore
&lt;/h3&gt;&lt;p&gt;OneDrive와 무관하게, &lt;code&gt;.gitignore&lt;/code&gt;를 꼼꼼하게 관리하기 시작했다. &lt;code&gt;build/&lt;/code&gt;, &lt;code&gt;.dart_tool/&lt;/code&gt;, &lt;code&gt;node_modules/&lt;/code&gt; 같은 폴더가 동기화되거나 추적되지 않도록. 이건 OneDrive 사건과 직접 관련은 없지만, 빌드 아티팩트가 소스 코드와 섞이면 안 된다는 걸 체감한 뒤로 더 신경 쓰게 됐다.&lt;/p&gt;
&lt;h2 id="돌이켜보면"&gt;&lt;a href="#%eb%8f%8c%ec%9d%b4%ec%bc%9c%eb%b3%b4%eb%a9%b4" class="header-anchor"&gt;&lt;/a&gt;돌이켜보면
&lt;/h2&gt;&lt;p&gt;클라우드 동기화 폴더에서 개발하는 건 시한폭탄이다. OneDrive, Dropbox, iCloud Drive — 전부 마찬가지다. 이 서비스들은 문서, 사진, 일반 파일을 동기화하도록 설계되었지, 수천 개의 임시 파일을 초 단위로 생성하고 삭제하는 개발 프로젝트를 위한 게 아니다.&lt;/p&gt;
&lt;p&gt;Git은 이미 완벽한 분산 백업 시스템이다. &lt;code&gt;git push&lt;/code&gt;만 해도 코드는 원격 저장소에 안전하게 보관된다. 그 위에 OneDrive까지 겹치면 동기화 충돌, 파일 잠금, 빌드 실패가 생기고, 최악의 경우 이 글처럼 작업이 통째로 날아간다.&lt;/p&gt;
&lt;p&gt;개발 폴더는 동기화 범위 밖에 둬라. 백업은 Git에 맡겨라. 그리고 커밋은 자주 해라.&lt;/p&gt;</description></item></channel></rss>