git pull 명령어는 원격 리포지토리의 변경사항을 가져오는(fetch) 동시에 로컬 브랜치에 병합(merge)합니다.
git pull origin main
이렇게 fetch와 merge가 나눠져 있는 이유는 무엇일까요?
가장 큰 이유는 변경 사항을 확인하기 위함입니다.
fetch를 통해 원격 리포지토리의 변경사항을 로컬에 가져온 후, 실제로 병합하기 전에 이러한 변경사항을 검토할 수 있습니다.
이는 병합에 따른 영향을 이해하고 준비하는 데 도움이 됩니다.
fetch는 원격 리포지토리의 최신 변경사항을 로컬로 가져오지만, 로컬의 작업 브랜치에는 자동으로 반영하지 않습니다.
원격 리포지토리에 새로운 커밋이 있을 때, 이 변경사항을 로컬 브랜치에 적용하기 위해서는 merge가 필요합니다.
createdDateTime과 lastModifiedDateTime을 비교해서 변동 사항이 있는 일정만 필터링을 하고 싶었습니다.
그런데 수정사항이 없던 일정도 계속 보여지는 일들이 발생해서 아예 로그를 찍었습니다.

알고보니 처음 만들어진 일정도 createdDateTime과 lastModifiedDateTime이 미묘하게 다른 것이었습니다.
이는 아래와 같은 이유 때문일 것이라고 추측됩니다.
시간대 처리: 시간대 변환 또는 서버와 클라이언트 간의 시간 처리 방식 차이로 인해 미묘한 시간 차이가 발생할 수 있습니다.
Microsoft Graph API의 동작: API 자체에서 내부적으로 이벤트를 업데이트하면서 lastModifiedDateTime을 변경할 수 있습니다.
그래서 유의미한 변경만 추적하는 것으로 해결 방안을 생각했습니다.
lastModifiedDateTime과 createdDateTime의 차이가 일정 기준 이상일 때만 이벤트가 수정된 것으로 간주할 수 있습니다.
예를 들어, 몇 분 또는 몇 시간의 차이 같은 것을 기준으로 삼을 수 있습니다.
저 같은 경우 createdDateTime과 lastModifiedDateTime 1분 이상의 차이가 나면 유의미한 변경이라고 생각했습니다.
import requests
import datetime
from dateutil.relativedelta import relativedelta
import cache
import app_config
def parse_iso_datetime(iso_str):
iso_str = iso_str.rstrip('Z')
if '.' in iso_str:
parts = iso_str.split('.')
iso_str = parts[0] + '.' + parts[1][:6]
return datetime.datetime.fromisoformat(iso_str)
def is_significant_change(created_time, modified_time):
time_diff = modified_time - created_time
return time_diff.total_seconds() >= 5
def get_updated_events():
token = cache._get_token_from_cache(app_config.SCOPE)
if not token:
return None
last_checked = (datetime.datetime.utcnow() - relativedelta(months=1)).isoformat() + 'Z'
current_time = datetime.datetime.utcnow().isoformat() + 'Z'
endpoint = app_config.ENDPOINT.format(current_datetime=last_checked, end_datetime=current_time)
headers = {'Authorization': 'Bearer ' + token['access_token']}
response = requests.get(endpoint, headers=headers)
current_events = response.json().get('value', [])
updated_events = []
for event in current_events:
created_time = parse_iso_datetime(event['createdDateTime'])
modified_time = parse_iso_datetime(event['lastModifiedDateTime'])
if created_time != modified_time and is_significant_change(created_time, modified_time):
updated_events.append(event)
return updated_events
def start_polling(scheduler):
scheduler.add_job(
func=get_updated_events,
trigger='interval',
minutes=5
)
이번 교훈을 통해서 뭔가 잘 안되면 로그를 찍어보자고 생각했습니다.
그리고 어처피 붙들고 있는 것 해결도 안되어서 다음 날 해결하는 것이 더 나을 수도 있습니다.
json 파일에서 UTC 기준으로 들어오기 때문에 네덜란드 보다 한 시간 이르게 시간이 표시되었습니다.
from dateutil import parser
def format_start_date(value):
date_time = parser.parse(value)
return date_time.strftime('%d-%m-%Y %H:%M')
def format_end_time(value):
date_time = parser.parse(value)
return date_time.strftime('%H:%M')
그래서 암스테르담 기준으로 바꾸기 위해서 pytz 라이브러리를 이용하였습니다.
from dateutil import parser
import pytz
def to_local_timezone(utc_datetime, local_timezone):
local_tz = pytz.timezone(local_timezone)
return utc_datetime.astimezone(local_tz)
def format_start_date(value, local_timezone='Europe/Amsterdam'):
utc_date_time = parser.parse(value)
utc_date_time = utc_date_time.replace(tzinfo=pytz.utc) # UTC 시간대 설정
local_date_time = to_local_timezone(utc_date_time, local_timezone)
return local_date_time.strftime('%d-%m-%Y %H:%M')
def format_end_time(value, local_timezone='Europe/Amsterdam'):
utc_date_time = parser.parse(value)
utc_date_time = utc_date_time.replace(tzinfo=pytz.utc) # UTC 시간대 설정
local_date_time = to_local_timezone(utc_date_time, local_timezone)
return local_date_time.strftime('%H:%M')